gep*_*cel 7 matplotlib cartopy
代码优先:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
ax = plt.axes(projection=ccrs.Mercator())
ax.set_extent([72, 135, 18, 53])
ax.annotate('hello', xy=(100, 49), xycoords='data',
transform=ccrs.PlateCarree(), zorder=12)
plt.show()
Run Code Online (Sandbox Code Playgroud)
结果不是预期的结果,我对我的方法有其他怀疑.所以我的问题是:
如果我想绘制地图看起来像网络地图(例如谷歌地图).地图区域可能与中国一样大,大部分都不是全球性的.谷歌搜索后,这些网站大多使用"网络墨卡托"投影.所以我想我应该plt.axes(projection=ccrs.Mercator()在这里使用,我是对的吗?或者如果我错了我该怎么用?
我想绘制的坐标数据类似于121°E,49°N(在绘制航线之前将度数转换为十进制),未投影,WGS84坐标系统,可能来自GPS.我有权使用transform=ccrs.PlateCarree()吗?或者如果我错了我该怎么用?
在annotate上述说明不了什么.在对该ax.set_extent行进行注释之后,将"hello"文本绘制在零(0,0)点处.我想要的是在点(100°E,49°N)如何纠正这个?
pel*_*son 14
首先 - 感谢代码 - 它使得解决问题变得容易多了.
说实话,我认为注释之前并没有真正使用过Cartopy,所以这可能就是你遇到这个问题的原因 - 你是开始炽热的;)
看起来matplotlib的Axes.annotate方法应该归咎于此 - 它通过https://github.com/matplotlib/matplotlib/blob/master/lib/matplotlib/axes/_axes.py#L651来克服变换.这主要是因为注释有特殊的关键字来定义的变换两者的坐标和文本位置独立(见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,一切都应该是hunky-dory.遗憾的是,annotate不知道如何将matopy坐标系转换为matplotlib变换,就像matplotlib的其余部分所做的那样,所以我们必须预先为annotate函数做到这一点.
要从任何折叠坐标系创建matplotlib变换,对于任何轴,我们可以简单地执行:
ax = plt.axes(projection=ccrs.Mercator())
crs = ccrs.PlateCarree()
transform = crs._as_mpl_transform(ax)
Run Code Online (Sandbox Code Playgroud)
我们现在可以将此转换传递给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()
Run Code Online (Sandbox Code Playgroud)

在回答您的其他问题时:
如果我想绘制地图看起来像网络地图(例如谷歌地图)
cartopy.crs中有一个新常量,它完全定义了Google Mercator(cartopy.crs.GOOGLE_MERCATOR).这只是Mercator投影的一个实例,只需进行一些调整就可以使其与Google Mercator完全相同(https://github.com/SciTools/cartopy/blob/master/lib/cartopy/crs.py#L889).
我想绘制的坐标数据类似于121°E,49°N(在绘制航线之前将度数转换为十进制),未投影,WGS84坐标系统,可能来自GPS.所以我使用transform = ccrs.PlateCarree()是对的吗?或者如果我错了我该怎么用?
我建议你最好使用大地坐标系 - 这个坐标系默认使用WGS84基准面,它可以让你最准确地表示你的WGS84纬度和经度.虽然,在你正在绘制它们的尺度上,我想你会很难注意到这种差异(中纬度地区的最大差异约为22Km).
HTH,