I'm making figures of some galaxies velocities with matplotlib
, from some .fits
files. The problem is that the axes in the figure show the galaxy's size in pixels, and I want to display them as Declination and RightAcension (in angle units). I already know that each pixel has a size of 0.396 arcseconds. How can I convert pixels to arcseconds in both X and Y axes?
The code is the folowing:
##############################################################################
# Generally the image information is located in the Primary HDU, also known
# as extension 0. Here, we use `astropy.io.fits.getdata()` to read the image
# data from this first extension using the keyword argument ``ext=0``:
image_data = fits.getdata(image_file, ext=0)
##############################################################################
# The data is now stored as a 2D numpy array. Print the dimensions using the
# shape attribute:
print(image_data.shape)
##############################################################################
# Display the image data:
fig = plt.figure()
plt.imshow(image_data, cmap='Spectral_r', origin='lower', vmin=-maior_pixel, vmax=maior_pixel)
plt.colorbar()
fig.suptitle(f'{gals_header["MANGAID"]}', fontsize=20, fontweight='bold')
ax = fig.add_subplot(111)
fig.subplots_adjust(top=0.85)
ax.set_title('RC')
ax.set_xlabel('pixelsx')
ax.set_ylabel('pixelsy')
There is more code than that, but I just want to show what I believe to be the relevant part (I can put more of it in the coments if necessary). This code is based on an example code from this link: https://docs.astropy.org/en/stable/generated/examples/io/plot_fits-image.html#sphx-glr-download-generated-examples-io-plot-fits-image-py
I already tried some things like Axes.convert_xunits
and some pyplot.axes
functions, but nothing worked (or maybe I just couldn't figure out how to properly use them).
That is how the Image is currently
Can someone help? Thank you in advance.
You can use whatever you want as the tick labels using a plt.FuncFormatter
object.
Here an example (a very silly one indeed), please refer to the excellent Matplotlib docs for the details.
import matplotlib.pyplot as plt
from numpy import arange
img = arange(21*21).reshape(21,21)
ax = plt.axes()
plt.imshow(img, origin='lower')
ax.xaxis.set_major_formatter(
plt.FuncFormatter(lambda x, pos: "$\\frac{%d}{20}$"%(200+x**2)))
Each axis has a major_formatter
that is responsible for generating the tick labels.
A formatter must be an instance of a class subclassed from Formatter
, above we used the FuncFormatter
.
To initialize a FuncFormatter
we pass to it a formatting function that we have to define with the following required characteristics
x
and pos
, x
being the abscissa (or the ordinate) to be formatted while pos
could safely be ignored,In the example the function has been defined on the spot using the lambda
syntax, the gist of it being a format string ("$\\frac{%d}{20}$"%(200+x**2)
) that formats as a LaTeX
fraction a function of the abscissa, as you can see in the picture above.
Re the pos
parameter, as far as I know it's used only in some methods, e.g.
In [69]: ff = plt.FuncFormatter(lambda x, pos: "%r ፨ %05.2f"%(pos,x))
In [70]: ff.format_ticks((0,4,8,12))
Out[70]: ['0 ፨ 00.00', '1 ፨ 04.00', '2 ፨ 08.00', '3 ፨ 12.00']
but in general you can ignore the pos
argument in the body of the function.