使用 Cartopy 绘制跨越国际日期变更线的线

问题描述

我正在尝试绘制全球风暴轨迹,但是当风暴穿过日期变更线(经度从 ~360 到 ~0)时,这条线会一直围绕绘图空间循环。 Here's what the plot looks like. See the weird straight lines near the top. 这是我的代码

ax = plt.axes(projection=ccrs.Robinson())
ax.set_global()

ax.coastlines()

for i in range(nstorms-1): #loop through each TC
        bidx = start_idx[i]
        eidx = start_idx[i+1]
        plt.plot(clons[bidx:eidx],clats[bidx:eidx],transform=ccrs.PlateCarree())

如果我尝试将变换更改为大地测量,它看起来像这样:

this is what happens

解决方法

根据 this github issue,这是预期行为,因为 PlateCarree 是投影坐标系。

PlateCarree 坐标系是笛卡尔坐标系,其中两点之间的线是直线(在该坐标系中)。笛卡尔系统不知道日期变更线/反经线,因此当您要求在 -170 和 +170 之间的线时,您会得到一条长度为 340 的线。 PlateCarree 投影永远不会解释这些数字并选择绘制一个非笛卡尔线

一种解决方案是在绘图调用中使用测地变换:

plt.plot(clons[bidx:eidx],clats[bidx:eidx],transform=ccrs.Geodetic())

或者修改您的数据以在使用 PlateCarree 系统时更有意义,例如通过识别值从 360-> 0 循环的位置并将 360 添加到发生后的所有值。您可以将它们移动到不同的范围(例如 -180..180),但是您会遇到与当前 0/360 相同的数据跨越 +/- 180 的问题。

,

要绘制跨越日期变更线的折线,您需要正确地对经度进行消毒。例如,值 359 到 2 应调整为 359 到 362。在下面的演示代码中,sanitize_lonlist() 用于在使用经度值列表绘制红色锯齿线之前对其进行清理。

import cartopy.crs as ccrs
import matplotlib.pyplot as plt

def sanitize_lonlist(lons):
    new_list = []
    oldval = 0
    treshold = 10  # used to compare adjacent longitudes
    for ix,ea in enumerate(lons):
        diff = oldval - ea
        if (ix>0):
            if (diff>treshold):
                ea = ea+360
        oldval = ea
        new_list.append(ea)
    return new_list

ax = plt.axes(projection=ccrs.Robinson()) 
ax.set_global() 
ax.coastlines(alpha=0.3)

# sample long/lat data for demo purposes
# xdateline: list of longitudes that cross dateline several times
xdateline = [347,349,352,358,4,7,8,3,359,360,5,1,357,12,6,349]
# ydateline: list of accompanying latitudes
ydateline = range(len(xdateline))

# plot the line crossing dateline using `sanitized` values of longitudes
plt.plot(sanitize_lonlist(xdateline),ydateline,transform=ccrs.PlateCarree(),color='red') 

plt.show()

datelinexing

使用 xdateline 的原始值绘制代码行:-

plt.plot(xdateline,color='red')

情节将是:-

bad-plot

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...