【问题标题】:Straight line through the pole with Cartopy stereographic projection使用 Cartopy 立体投影的直线穿过杆
【发布时间】:2012-12-28 08:42:27
【问题描述】:

我正在使用 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()

为了解决这个问题,我必须将 x 和 y 更改为:

x=[180,180,0,0]
y=[50,90,90,50]

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

编辑:附上图片

谢谢,

提姆

【问题讨论】:

标签: matplotlib cartopy


【解决方案1】:

我认为您在绘制此部分时需要使用大地变换而不是 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()

结果如下:

我认为无论如何这是处理这个问题的正确方法!

安德鲁

【讨论】:

    【解决方案2】:

    @ajdawson 的回答是正确的。在这种情况下,使用 Geodetic 变换就可以解决问题。

    要了解线条与预期不符的原因,我们需要了解 PlateCarree 变换所代表的含义。

    首先,让我们观察使用 Cartopy 在transform=&lt;projection&gt; 表单中绘制的所有线都应该通过相同的地理点,而与绘制线的投影无关。

    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 的事情变得更加清晰!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-02-20
      • 2012-11-25
      • 2012-03-05
      • 1970-01-01
      • 2017-07-03
      • 2015-10-17
      • 1970-01-01
      相关资源
      最近更新 更多