使用相同的投影在图像上绘制线条
Plotting lines over an image using the same projection
我想使用 .fits 文件(天文图像)作图,我遇到了两个我认为相关的问题:
使用来自 astropy 的这个例子:
from matplotlib import pyplot as plt
from astropy.io import fits
from astropy.wcs import WCS
from astropy.utils.data import download_file
fits_file = 'http://data.astropy.org/tutorials/FITS-images/HorseHead.fits'
image_file = download_file(fits_file, cache=True)
hdu = fits.open(image_file)[0]
wcs = WCS(hdu.header)
fig = plt.figure()
fig.add_subplot(111, projection=wcs)
plt.imshow(hdu.data, origin='lower', cmap='cubehelix')
plt.xlabel('RA')
plt.ylabel('Dec')
plt.show()
我可以生成这张图片:
现在我想使用与图像相同的坐标绘制一些点:
plt.scatter(85, -2, color='red')
但是,当我这样做时:
我正在像素坐标处绘图。此外,图像不再匹配帧大小(尽管坐标看起来很好)
关于如何处理这些问题有什么建议吗?
绘制给定坐标非常容易。您所要做的就是应用 transform
.
我复制了您的示例并在我更改的地方添加了评论以及原因。
from matplotlib import pyplot as plt
from astropy.io import fits
from astropy.wcs import WCS
from astropy.utils.data import download_file
fits_file = 'http://data.astropy.org/tutorials/FITS-images/HorseHead.fits'
image_file = download_file(fits_file, cache=True)
# Note that it's better to open the file with a context manager so no
# file handle is accidentally left open.
with fits.open(image_file) as hdus:
img = hdus[0].data
wcs = WCS(hdus[0].header)
fig = plt.figure()
# You need to "catch" the axes here so you have access to the transform-function.
ax = fig.add_subplot(111, projection=wcs)
plt.imshow(img, origin='lower', cmap='cubehelix')
plt.xlabel('RA')
plt.ylabel('Dec')
# Apply a transform-function:
plt.scatter(85, -2, color='red', transform=ax.get_transform('world'))
结果是:
请注意,如果您希望 Canvas 仅显示图像区域,只需在之后再次应用限制即可:
# Add a scatter point which is in the extend of the image:
plt.scatter(85.3, -2.5, color='red', transform=ax.get_transform('world'))
plt.ylim(0, img.shape[0])
plt.xlim(0, img.shape[1])
给出:
这里还有一个旁注。 AstroPy 有很好的单位支持,所以不用将 arcmins 和 arcsecs 转换为度数,你可以只定义 "unit"。不过你仍然需要转换:
from astropy import units as u
x0 = 85 * u.degree + 20 * u.arcmin
y0 = -(2 * u.degree + 25 * u.arcmin)
plt.scatter(x0, y0, color='red', transform=ax.get_transform('world'))
我想使用 .fits 文件(天文图像)作图,我遇到了两个我认为相关的问题:
使用来自 astropy 的这个例子:
from matplotlib import pyplot as plt
from astropy.io import fits
from astropy.wcs import WCS
from astropy.utils.data import download_file
fits_file = 'http://data.astropy.org/tutorials/FITS-images/HorseHead.fits'
image_file = download_file(fits_file, cache=True)
hdu = fits.open(image_file)[0]
wcs = WCS(hdu.header)
fig = plt.figure()
fig.add_subplot(111, projection=wcs)
plt.imshow(hdu.data, origin='lower', cmap='cubehelix')
plt.xlabel('RA')
plt.ylabel('Dec')
plt.show()
我可以生成这张图片:
现在我想使用与图像相同的坐标绘制一些点:
plt.scatter(85, -2, color='red')
但是,当我这样做时:
我正在像素坐标处绘图。此外,图像不再匹配帧大小(尽管坐标看起来很好)
关于如何处理这些问题有什么建议吗?
绘制给定坐标非常容易。您所要做的就是应用 transform
.
我复制了您的示例并在我更改的地方添加了评论以及原因。
from matplotlib import pyplot as plt
from astropy.io import fits
from astropy.wcs import WCS
from astropy.utils.data import download_file
fits_file = 'http://data.astropy.org/tutorials/FITS-images/HorseHead.fits'
image_file = download_file(fits_file, cache=True)
# Note that it's better to open the file with a context manager so no
# file handle is accidentally left open.
with fits.open(image_file) as hdus:
img = hdus[0].data
wcs = WCS(hdus[0].header)
fig = plt.figure()
# You need to "catch" the axes here so you have access to the transform-function.
ax = fig.add_subplot(111, projection=wcs)
plt.imshow(img, origin='lower', cmap='cubehelix')
plt.xlabel('RA')
plt.ylabel('Dec')
# Apply a transform-function:
plt.scatter(85, -2, color='red', transform=ax.get_transform('world'))
结果是:
请注意,如果您希望 Canvas 仅显示图像区域,只需在之后再次应用限制即可:
# Add a scatter point which is in the extend of the image:
plt.scatter(85.3, -2.5, color='red', transform=ax.get_transform('world'))
plt.ylim(0, img.shape[0])
plt.xlim(0, img.shape[1])
给出:
这里还有一个旁注。 AstroPy 有很好的单位支持,所以不用将 arcmins 和 arcsecs 转换为度数,你可以只定义 "unit"。不过你仍然需要转换:
from astropy import units as u
x0 = 85 * u.degree + 20 * u.arcmin
y0 = -(2 * u.degree + 25 * u.arcmin)
plt.scatter(x0, y0, color='red', transform=ax.get_transform('world'))