问题
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.
回答1:
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
- has two inputs,
x
andpos
,x
being the abscissa (or the ordinate) to be formatted whilepos
could safely be ignored, - returns a string to be used as the label.
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.
来源:https://stackoverflow.com/questions/61162537/how-do-i-change-the-axes-units-in-a-figure