Visualizing Astronomical Images#

Imad Pasha, Yasmeen Asali, William Cerny, Sebastian Monzon (Yale University)

Description: Practice writing Python functions + visualization of astronomical imaging

Intended Audience: Beginner to Intermediate Undergraduate

tags: library:matplotlib, control-flow:functions, visualization, astronomical-images

Requirements: requirements.txt

Last Updated: July 23, 2024

Learning Objectives

  • Write basic functions in Python

  • Be able to appropriately scale and view FITS images

Introduction#

Images taken by telescopes (both in space and on the ground) are a crucial element of astronomical research, providing a spatially resolved view of a region (generally at a particular wavelength). These images are predominantly stored in an astronomy-specific file type known as fits — flexible image transport system (though tables can also be stored in fits files)

The astropy.io module has a useful submodule for working with fits files, which can be imported as

from astropy.io import fits

Within a fits file, information is stored in what are called extensions. These are like separate buckets/folders, and thus allow one to store multiple images, or an image + table, or multiple tables, within 1 file. But often, we have a simple file with 1 image in the 0th extension. Every extension present in a fits file has two attributes: a .header attribute, and a .data attribute. The header is like a dictionary, storing ancillary information in key-value pairs, while the data attribute stores the image, table, etc.

When we load a fits file, we usually also want to know something about the coordinates (on the sky, so RA and DEC) of the objects in our image. To do this, we need to know the WCS (world coordinate system) information for the image, which provides a translation between position in pixel (image) coordinates and sky coordinates. For many astronomical images you will work with, this information has been added to the .header attribute for the extension of the image. The astropy.wcs.WCS class can be given such a header, and compute a wcs object that will be useful when we go to plot or determine locations in our image. We can import it via

from astropy.wcs import WCS

So how do we actually open a fits file and retrieve the image and header? We’ll use a pythonic structure known as a context manager. The details of context managers aren’t super important right now, but the key point is this: context managers let us open contexts and close them automatically. For files, this means we can open a fits file, extract what we need, and close the file automatically.

Opening a Fits File#

The fits file we will be using here is an image of M33 taken by the Dragonfly Spectral Line Mapper.

You can download it here (right click and save as a .fits file).

Writing an Image Opening Function#

We can, if we wish, encapsulate this operation into a function. It’s short enough that it’s not overly onerous to write out each time. But we can make these three lines into one, which might make our code easier to read when loading many different fits files throughout a script.

Recall that a function in Python is, like a mathematical function, designed to take input arguments (when needed) and return values back. So \(y = sin(x)\) is a function which takes \(x\) as an argument and returns something, which has been named \(y\) here. The default structure of a simple python function is

def function_name(arg1_name,arg2_name):
    computation = arg1_name * arg2_name 
    return computation

Here we use def to define a function (lines within the function are indented), and within the function, we assign inputs names to use when computing things, before returning some final value(s) if required.

Visualizing the Image#

Let’s visualize the image we have loaded.

A function for Image Viewing#

The code to visualize the image above is already a few lines of code, and we often need to plot astronomical images. Let’s now make a function that can streamline some of these lines of code above for us.

Next we want to incorporate the wcs into the mix, allowing us to easily view an image with axes either in pixels or in astronomical coordinates.

There are now a decent number of lines of logic and checking in our function, and hopefully it is becoming clear why making such a function is so useful — we can now very quickly and easily load and plot any fits file, or any array we have on hand, with wcs on or off, with limits setting, all in one line.

Note

It is a good idea to return the fig and ax objects at the end of our function. This is useful because if we want to add to our plot (say, add a circle somewhere, or text), or change our plot (adjust the limits, etc.) we need to be able to access those objects. As we learned when we discussed scope, anything from inside a function that we want access to after the function has been run must be returned back to the larger scope of the python script we are working in.