首先-感谢您的代码-它使解决问题变得更加容易。
老实说,我认为之前没有认真使用过 Cartopy 的注释,所以这可能就是你遇到这个问题的原因 - 你是开拓者;)
看起来 matplotlib 的Axes.annotate
方法应该归咎于此 - 它破坏了通过https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_axes.py#L651周围传递的变换。这主要是因为 annotate 具有用于独立定义坐标和文本位置变换的特殊关键字(xycoords
参见textcoords
http://matplotlib.org/users/annotations_intro.html#annotating-text )。
当我们深入到 Annotate 类时,我们会发现 Annotate 的_get_xy_transform
(https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/text.py#L1446)可以处理各种(一些未记录的)形式为的值textcoords
,包括转换实例。
好的,到目前为止,一切都很好。看起来你可以通过一个坐标系来xycoords
,一切都应该是笨拙的。遗憾的是,annotate 不知道如何将 Cartopy 坐标系转换为 matplotlib 转换,就像 matplotlib 的大多数其余部分所做的那样,所以我们必须预先为 annotate 函数做这件事。
要从任何 cartopy 坐标系创建 matplotlib 变换,对于任何轴,我们可以简单地执行以下操作:
ax = plt.axes(projection=ccrs.Mercator())
crs = ccrs.PlateCarree()
transform = crs._as_mpl_transform(ax)
我们现在可以将这个转换传递给 annotate 方法,我们应该在预期的位置得到文本和箭头。我采取了一些自由来突出注释的一些功能,而我正在使用它:
import cartopy.feature
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.Mercator())
ax.set_extent([65, 125, 5, 40])
ax.add_feature(cartopy.feature.OCEAN)
ax.add_feature(cartopy.feature.LAND)
ax.add_feature(cartopy.feature.BORDERS, linestyle=':', edgecolor='gray')
ax.coastlines()
ax.plot(116.4, 39.95, 'ob', transform=ccrs.PlateCarree())
transform = ccrs.PlateCarree()._as_mpl_transform(ax)
ax.annotate('Beijing', xy=(116.4, 39.9), xycoords=transform,
ha='right', va='top')
ax.annotate('Delhi', xy=(113, 40.5), xytext=(77.23, 28.61),
arrowprops=dict(facecolor='gray',
arrowstyle="simple",
connectionstyle="arc3,rad=-0.2",
alpha=0.5),
xycoords=transform,
ha='right', va='top')
plt.show()
在回答您的其他问题时:
如果我想绘制一个看起来像网络地图的地图(例如谷歌地图)
cartopy.crs 中有一个新常量,它准确地定义了谷歌墨卡托 ( cartopy.crs.GOOGLE_MERCATOR
)。这只是墨卡托投影的一个实例,经过一些调整,使其与谷歌墨卡托完全一样(https://github.com/SciTools/cartopy/blob/master/lib/cartopy/crs.py#L889)。
我想要绘制的坐标数据就像 121°E,49°N(当然在绘制之前将度数转换为十进制),未投影的 WGS84 坐标系统,可能来自 GPS。那么我使用 transform=ccrs.PlateCarree() 是否正确?或者如果我错了我应该使用什么?
我建议您最好使用 Geodetic 坐标系 - 此坐标系默认使用 WGS84 基准面,这将为您提供 WGS84 纬度和经度的最准确表示。虽然,按照您当前绘制的比例,我想您可能很难注意到差异(中纬度地区的最大差异约为 22 公里)。
高温下,