user7345804
user7345804

Reputation:

How to view this .fits image without resizing and without modifying colors?

I am trying to open a full-color image from a '.fits' file. But, when comparing it to the corresponding '.gif' image, there appears to be an error regarding its color and size.

How can I view the real-color image in its proper dimensions?

As an example, one can select the '.fits' file and corresponding '.gif' file located at the top of this webpage. My example code, which uses the APLPY module, is below.

def from_fits_to_image(color_scheme, rloc, rname='synop_Ml_0.2104', rext='.fits', cmap=None):
    """ 
    color_scheme : 'rgb', 'grayscale', or 'false color'; color scheme of image to be shown
    rloc         : type <str>; location of file to be read
    rname        : type <str>; name of file to be read
    rext         : type <str>; extension of file to be read
    cmap         : None or type <str>; colormap
    """
    rpath = rloc + rname + rext
    if color_scheme == 'rgb':
        pic = aplpy.FITSFigure(rpath)
        # pic.show_rgb(alt_filename) # what filename is supposed to go here?
    else:
        pic = aplpy.FITSFigure(rpath)
        if color_scheme == 'grayscale':
            pic.show_grayscale()
        elif color_scheme == 'false color':
            if cmap is None:
                pic.show_colorscale()
            else:
                pic.show_colorscale(cmap=cmap)
    # plt.savefig(...)
    plt.show()

So long as one provides the proper rloc (the location of the downloaded '.fits' file) and color_scheme, the above code will run.

Calling the function below will show an empty plot of the proper dimensions. To make it non-empty, I must supply another existing filename, though I am unclear on what exactly that should be.

from_fits_to_image(color_scheme='rgb', rloc=rloc) 

enter image description here

Each of the function calls below reveal a plot that has been resized to small. While color_scheme='grayscale' seems to colorize the plot properly, the other methods do not properly colorize the image.

from_fits_to_image('grayscale', rloc=rloc)

enter image description here

from_fits_to_image('false color', rloc=rloc)

enter image description here

from_fits_to_image('false color', rloc=rloc, cmap='plasma')

enter image description here

For comparison, the '.gif' image is below. Ideally, the output will look exactly like the image below.

EDIT:

I have tried using astropy, PIL, and pyfits unsuccessfully. Any help would be appreciated.

enter image description here

EDIT 2:

Below is the result using fits from astropy.io.

from astropy.io import fits

def reada(rloc, rname='synop_Ml_0.1998', rext='.fits'):
    """ """
    rpath = rloc + rname + rext
    # hdu_list = fits.open(rpath)
    # hdu_list.info()
    pic = fits.getdata(rpath)
    plt.imshow(pic)
    plt.show()

reada(rloc=rloc)

I've played with the vmin and vmax kwargs, but to no success. Also, using pyfits to open the file results in the following error, even when using pyfits.open(rpath, uint=True, do_not_scale_image_data=True):

TypeError: Image data can not convert to float

enter image description here

Upvotes: 1

Views: 712

Answers (1)

Vlas Sokolov
Vlas Sokolov

Reputation: 3893

Judging from the gif, it seems that the image is a false-color one, and it's a matter of choosing a right color map. I can't say if there's an equivalent color map in python to the one you've linked to, but we can find something that is pretty close, recreating all the features in the image:

fig = aplpy.FITSFigure('synop_Ml_0.2104.fits')
fig.show_colorscale(vmin=-60, vmax=60, cmap='hot')

which shows the following (note that aplpy does not understand this coordinate system so it plots the figure in pixel coordinates): enter image description here

The second part of the question is more tricky, and I can't fully answer it. Firstly, you need to convert the Carrington time into longitude, and sine latitude into degrees, and then plot the new values for the axis labels either instead of the old ones or as a parasite axes alongside the old ones (you can refer to an parasite axes example here).

Now it looks like the Carrington time is just degrees rotated since November 9, 1853, and the x-axis spans exactly 360, so I assume the conversion is simply an offset by 757079.95, the the x-axis value at the left edge. We can double-check it on the world coordinates, by looking at how the pixel span of the map corresponds to the coordinate span:

In [88]: fig._wcs.wcs_pix2world(fig._ax1.get_xlim(), fig._ax1.get_ylim(), origin=1)
Out[88]: [array([757439.95, 757079.95]), array([-1.,  1.])]

and the difference in values for the xaxis edges, 757079.95 and 757439.95, is exactly 360 degrees.

So then we can use some matplotlib tricks to manually offset the coordinate values to force them to go from zero to 360 and get the xaxis to match your gif image:

# using hidden attributes is non-pythonic but aplpy does not leave us other options
ax = fig._ax1
x_range = ax.get_xlim()
new_ticklabels = np.arange(60, 361, 60)
new_tick_positions = new_ticklabels / 360. * x_range[1] + x_range[0]
ax.set_xticks(new_tick_positions)
ax.set_xticklabels(new_ticklabels)
fig.axis_labels.set_xtext('Carrington Longitude')

enter image description here

Keep in mind that aplpy is a library designed for plotting celestial, not solar, coordinates, so getting the axes transform to work properly could be a rather painful process. An alternative way, and perhaps a better one, would be to plot the fits file with sunpy, a python library for solar physics. However, I have never used it, and it seems to throw an error for this particular fits file. Looks like you need to modify the header of the fits file to get the coordinates properly read. Perhaps you can get in touch with sunpy community if you want to use the library?

Upvotes: 2

Related Questions