使用Astropy绘制天区与散点图的坐标匹配问题
问题描述
尝试用Astropy绘制天区并叠加散点图时遇到坐标系/Matplotlib元素异常:
- 定义天区的代码如下:
import matplotlib.pyplot as plt import astropy.units as u from gammapy.maps import RegionGeom from astropy.coordinates import SkyCoord, CircleSkyRegion ra, dec = 60 * u.deg, 85 * u.deg center = SkyCoord(ra=ra, dec=dec) angle = 1 * u.deg region = RegionGeom(CircleSkyRegion(center, angle))
- 直接调用
region.plot_region()能正常绘制天区,但添加度数单位的散点(如天区中心)时,因当前轴为归一化像素坐标(范围0-1),散点无法显示; - 提前定义绑定
region.wcs投影的轴后,散点能正常显示,但天区却偏移出可视区域。
想问:两种轴定义的差异是什么?如何实现同时绘制受坐标系变形的天区与其他元素?
问题解答
一、两种轴定义的核心差异
- 自动创建的默认轴:
这是Matplotlib原生的笛卡尔轴,未关联天文投影(WCS)。region.plot_region()会自动将天区的天文坐标转换为该轴下的归一化像素坐标(0-1范围)进行绘制。此时轴的坐标系统是Matplotlib的像素/归一化坐标,与天文度数完全不兼容,直接用度数坐标画散点会超出可视范围。 - 手动绑定WCS的轴:
这种轴绑定了天文投影规则,坐标系统为RA/Dec度数。但直接创建该轴后调用region.plot_region()会出现天区偏移——因为region.plot_region()默认会再次自动转换坐标,相当于做了两次投影转换,导致天区被映射到错误位置。
二、正确实现方法
要统一坐标系统,让所有元素基于同一个WCS投影绘制,步骤如下:
- 先创建绑定WCS的轴:
使用plt.subplot(projection=region.wcs)创建带天文投影的轴,使轴的坐标系统统一为RA/Dec度数; - 绘制天区时禁用重复坐标转换:
调用region.plot_region()时,指定ax参数为创建的WCS轴,同时设置transform=ax.get_transform('world'),让天区直接使用轴的世界坐标(天文度数)绘制; - 直接用天文坐标绘制散点:
因为轴已绑定WCS投影,直接传入天区中心的度数坐标调用ax.scatter()即可。
完整代码示例:
import matplotlib.pyplot as plt import astropy.units as u from gammapy.maps import RegionGeom from astropy.coordinates import SkyCoord, CircleSkyRegion ra, dec = 60 * u.deg, 85 * u.deg center = SkyCoord(ra=ra, dec=dec) angle = 1 * u.deg region = RegionGeom(CircleSkyRegion(center, angle)) # 创建绑定WCS投影的轴 fig, ax = plt.subplots(subplot_kw={'projection': region.wcs}) # 绘制天区,指定轴与世界坐标转换规则 region.plot_region(ax=ax, transform=ax.get_transform('world'), edgecolor='red', lw=2) # 绘制天区中心散点 ax.scatter(center.ra.deg, center.dec.deg, marker='*', color='blue', s=100) # 设置轴标签 ax.set_xlabel('Right Ascension (deg)') ax.set_ylabel('Declination (deg)') plt.show()
补充说明
- 后续添加其他天文元素(如其他天区、源位置)时,需确保使用同一个WCS轴,并基于世界坐标(度数)绘制;
- 你的天区中心Dec为85°(极区附近),建议使用适合极区的投影(如
AIT或STG)减少变形。可手动创建指定投影的WCS对象:
from astropy.wcs import WCS wcs = WCS(naxis=2) wcs.wcs.crpix = [100, 100] wcs.wcs.cdelt = [-0.01, 0.01] wcs.wcs.crval = [center.ra.deg, center.dec.deg] wcs.wcs.ctype = ["RA---AIT", "DEC--AIT"] # 使用自定义WCS创建轴 fig, ax = plt.subplots(subplot_kw={'projection': wcs})
内容的提问来源于stack exchange,提问作者Euler
相关产品推荐
相关产品推荐

