TGr*_*ham 4 matplotlib cartopy
我正在使用cartopy来生成具有立体投影的北极地图,然后在顶部绘制一条线(以显示横截面的位置).如果我使用下面的代码,那么这条线不是直线穿过极点,而是沿着一条纬线.
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
x=[180,0]
y=[50,50]
ax = plt.axes(projection=ccrs.NorthPolarStereo())
ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree())
ax.plot(x,y,transform=ccrs.PlateCarree())
plt.gca().stock_img()
plt.gca().coastlines()
plt.show()
Run Code Online (Sandbox Code Playgroud)
为了解决这个问题,我必须将x和y更改为:
x=[180,180,0,0]
y=[50,90,90,50]
Run Code Online (Sandbox Code Playgroud)
所以北极有两个数据点.有更好的解决方案吗?
编辑:附加图像

谢谢,
蒂姆
@ ajdawson的回答是正确的.在这种情况下,使用大地测量变换就可以了.
要理解线条不符合预期的原因,我们需要了解PlateCarree变换代表什么.
首先,让我们观察一下transform=<projection>,使用Cartopy 在表单中绘制的所有线条都应该通过相同的地理点,而不管绘制线条的投影如何.
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()
Run Code Online (Sandbox Code Playgroud)

因此,回到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()
Run Code Online (Sandbox Code Playgroud)

您会发现该线路与原始问题中的坏线路经过相同的地理点.
这应该让你满意的是,Cartopy的行为是合理的并且它不是一个bug,但它并没有回答关于你如何绘制你想要的线的问题.
@ajdawson已经说过,在你的情况下,绘制线:
plt.plot([180, 0], [50, 50] , transform=ccrs.Geodetic())
Run Code Online (Sandbox Code Playgroud)
将产生所需的输出.
这是因为大地坐标参考系统在两点之间绘制地球上最短距离的线.但是,当穿过北极时,将有一个纬度不提供最短距离:
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()
Run Code Online (Sandbox Code Playgroud)

通常,如果您想绘制始终穿过北极的大地测量线,那么北极应该是该线的坐标之一.
plt.plot([180, 0, 0], [-45, 90, -45] , transform=ccrs.Geodetic())
Run Code Online (Sandbox Code Playgroud)
最后,只是把它扔进混音中,如果你只是想要穿过北极的北极立体投影中的垂直线,那么值得记住存在笛卡尔坐标系(其中值得记住的是数字)不是纬度和经度),所以干脆做:
ax = plt.axes(projection=ccrs.NorthPolarStereo())
plt.axvline()
Run Code Online (Sandbox Code Playgroud)
也会做的伎俩!(但比大地测量法更不易转移)
哇,我的答案很长.我希望你和我在一起,这让整个PlateCarree的事情变得更加清晰!
我认为在绘制此部分时您需要使用大地测量变换而不是 Plate Carree:
<!-- language: lang-py -->
import cartopy.crs as ccrs
import matplotlib.pyplot as plt
x=[180,0]
y=[50,50]
ax = plt.axes(projection=ccrs.NorthPolarStereo())
ax.set_extent([0, 360, 50, 90], crs=ccrs.PlateCarree())
ax.plot(x,y,transform=ccrs.Geodetic())
ax.stock_img()
ax.coastlines()
plt.show()
Run Code Online (Sandbox Code Playgroud)
结果如下:

我认为无论如何这都是正确的处理方式!
安德鲁
| 归档时间: |
|
| 查看次数: |
1612 次 |
| 最近记录: |