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

2024-10-01 05:06:16 发布

您现在位置:Python中文网/ 问答频道 /正文

我试图绘制全球风暴轨迹,但当风暴穿过日期线(经度从~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


Tags: the绘图plot轨迹绘制pltaxstart
2条回答

要绘制跨越日期线的多段线,需要正确清理经度。例如,值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,358,360,3,5,359,1,357,0,8,12,6,357,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, ydateline, transform=ccrs.PlateCarree(), color='red')

该地块将为:-

bad-plot

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

The PlateCarree coordinate system is Cartesian where a line between two points is straight (in that coordinate system). The Cartesian system has no knowledge of datelines/antimeridians and so when you ask for a line between -170 and +170 you get a line of length 340. It can never be the case that the PlateCarree projection interprets these numbers and chooses to draw a non-cartesian line

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

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

或者在使用PlateCarree系统时修改数据以使其更有意义,例如,通过标识值从360->;0,然后将360添加到所有值。您可以将它们移到不同的范围(例如-180..180),但数据交叉+/-180的问题与当前0/360的问题相同

相关问题 更多 >