@ajdawson 的回答是正确的。在这种情况下,使用 Geodetic 变换就可以解决问题。
要了解线条与预期不符的原因,我们需要了解 PlateCarree 变换所代表的含义。
首先,让我们观察使用 Cartopy 在transform=<projection> 表单中绘制的所有线都应该通过相同的地理点,而与绘制线的投影无关。
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
def main():
x=[180, 180, 0, 0]
y=[50, 90, 90, 50]
# plot2 - North Polar Stereographic
ax = plt.subplot(211, projection=ccrs.NorthPolarStereo())
ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree())
ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2)
ax.stock_img()
ax.coastlines()
# plot2 - PlateCarree
ax = plt.subplot(212, projection=ccrs.PlateCarree(central_longitude=45))
ax.set_extent([0, 360, -45, 90], crs=ccrs.PlateCarree())
ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2)
ax.stock_img()
ax.coastlines()
plt.show()
if __name__ == '__main__':
main()
所以回到在 PlateCarree 地图上绘制原始坐标(在 PlateCarree 坐标中):
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
def main():
x=[180, 0]
y=[50, 50]
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=45))
ax.set_extent([0, 360, -45, 90], crs=ccrs.PlateCarree())
ax.plot(x, y, transform=ccrs.PlateCarree(), color='red', lw=2)
ax.stock_img()
ax.coastlines()
plt.tight_layout()
plt.show()
if __name__ == '__main__':
main()
你会发现这条线和你原来问题中的坏线穿过了相同的地理点。
这应该让您满意,Cartopy 的行为是合理的,它不是错误,但它不能回答关于 如何 绘制所需线条的问题。
@ajdawson 已经说过,在你的情况下,画线:
plt.plot([180, 0], [50, 50] , transform=ccrs.Geodetic())
将产生所需的输出。
这是因为大地坐标参考系统在地球上绘制了两点之间最短距离的线。但是,会有一个纬度,当穿过北极时,它不会提供最短距离:
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
def main():
ax = plt.axes(projection=ccrs.PlateCarree(central_longitude=45))
ax.set_global()
ax.plot([180, 0], [20, 20], transform=ccrs.Geodetic(), color='red', lw=2, label='Latitude = 20')
ax.plot([180, 0], [0, 0], transform=ccrs.Geodetic(), color='blue', lw=2, label='Latitude = 0')
ax.plot([180, 0], [-20, -20], transform=ccrs.Geodetic(), color='yellow', lw=2, label='Latitude = -20')
ax.outline_patch.set_zorder(2)
plt.legend(loc=8, bbox_to_anchor=(0.65, -0.2), shadow=True, fancybox=True)
ax.stock_img()
ax.coastlines()
plt.tight_layout()
plt.show()
if __name__ == '__main__':
main()
一般来说,如果你想画一条总是穿过北极的大地线,那么北极应该是这条线的坐标之一。
plt.plot([180, 0, 0], [-45, 90, -45] , transform=ccrs.Geodetic())
最后,只是为了把它混在一起,如果你只是想要一条穿过北极的北极立体投影中的垂直线,那么值得记住存在笛卡尔坐标系(其中值得记住数字不是纬度和经度),所以只需这样做:
ax = plt.axes(projection=ccrs.NorthPolarStereo())
plt.axvline()
也可以解决问题! (但不如大地测量方法可移植)
哇,我的回答太长了。我希望你仍然和我在一起,这会让整个 PlateCarree 的事情变得更加清晰!