How do I change the axes' units in a figure?

£可爱£侵袭症+ 提交于 2021-01-28 09:37:42

问题


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 and pos, x being the abscissa (or the ordinate) to be formatted while pos 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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!