gpt4 book ai didi

matplotlib - 使用 Cartopy 立体投影穿过杆的直线

转载 作者:行者123 更新时间:2023-12-04 23:05:07 24 4
gpt4 key购买 nike

我正在使用 cartopy 制作带有立体投影的北极 map ,然后在顶部绘制一条线(以显示横截面的位置)。如果我使用下面的代码,那么这条线不会穿过极点,而是沿着一条纬度线。

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()

为了解决这个问题,我必须将 x 和 y 更改为:
x=[180,180,0,0]
y=[50,90,90,50]

所以北极有两个数据点。有没有更好的解决方案?

编辑 :附上图片
What is desired

谢谢,

蒂姆

最佳答案

@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()

output image - north polar stereo next to PlateCarree

所以回到在 PlateCarree map 上绘制原始坐标(在 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()

PlateCarree line

您会发现该线与原始问题中的坏线穿过相同的地理点。

这应该让您满意 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()

Non-north pole crossing geodetic lines

一般来说,如果你想画一条总是穿过北极的大地线,那么北极应该是这条线的坐标之一。
plt.plot([180, 0, 0], [-45, 90, -45] , transform=ccrs.Geodetic())

最后,只是为了把它混在一起,如果你只是想要一条穿过北极的北极立体投影中的垂直线,值得记住的是存在一个笛卡尔坐标系(其中值得记住的是数字不是纬度和经度),所以简单地做:
ax = plt.axes(projection=ccrs.NorthPolarStereo())
plt.axvline()

也会做的伎俩! (但不如大地测量方法可转移)

哇,我的答案很长。我希望你还在我身边,这让整个 PlateCarree 事情变得更加清晰!

关于matplotlib - 使用 Cartopy 立体投影穿过杆的直线,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14317596/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com