空流图:Cartopy 和经度坐标范围 [0, 360]

问题描述 投票:0回答:1

我正在尝试使用 xarray 和 cartopy 在地图上绘制流图。但是,图形是空的。我正在使用 NCEP 再分析 2 中的风组件,该文件可在 here 中找到。此数据的经度坐标范围为 0 到 360 度,经度坐标范围为 90 到 -90 度。

在没有地图的情况下绘制流线图按预期工作(我必须通过增加纬度对数据进行排序,正如 streamplot 函数所预期的那样):

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

dados = xr.open_dataset('u_v_sample_data.nc')
dados = dados.sortby('lat')

lc = dados.sel(time='2023-03-17-00',
               level=250,
               lat=slice(-60,10),
               lon=slice(270,330)).plot.streamplot(x='lon',
                                                   y='lat',
                                                   u='u',
                                                   v='v')

vetores = dados.sel(time='2023-03-17-00',
                     level=250,
                     lat=slice(-60,10),
                     lon=slice(270,330)).plot.quiver(x='lon',
                                                     y='lat',
                                                     u='u',
                                                     v='v')

plt.show()

此代码创建以下情节:

当尝试使用 cartopy 在地图上绘制相同的数据时,我得到一个空图形(矢量图工作正常,而不是):

mapa = plt.axes( projection=ccrs.PlateCarree() )

lc = dados.sel(time='2023-03-17-00',
               level=250,
               lat=slice(-60,10),
               lon=slice(270,330)).plot.streamplot(x='lon',
                                                   y='lat',
                                                   u='u',
                                                   v='v',
                                                   transform = ccrs.PlateCarree(),
                                                   density=5,
                                                  ax=mapa)

vetores = dados.sel(time='2023-03-17-00',
                     level=250,
                     lat=slice(-60,10),
                     lon=slice(270,330)).plot.quiver(x='lon',
                                                     y='lat',
                                                     u='u',
                                                     v='v',
                                                     transform = ccrs.PlateCarree(),
                                                    ax=mapa)
mapa.gridlines(draw_labels=True)
mapa.coastlines()
plt.show()

结果如下图:

最后,cartopy map画流线只有经度坐标变换到[-180,180]范围才有效,如下图(注意slice函数中的经度坐标):

dados.coords['lon'] = ( ( dados.coords['lon'] + 180 ) % 360 ) - 180
dados = dados.sortby( dados.lon )

mapa = plt.axes( projection=ccrs.PlateCarree() )

lc = dados.sel(time='2023-03-17-00',
               level=250,
               lat=slice(-60,10),
               lon=slice(-90,-30)).plot.streamplot(x='lon',
                                                   y='lat',
                                                   u='u',
                                                   v='v',
                                                   transform = ccrs.PlateCarree(),
                                                   density=5,
                                                  ax=mapa)

vetores = dados.sel(time='2023-03-17-00',
                     level=250,
                     lat=slice(-60,10),
                     lon=slice(-90,-30)).plot.quiver(x='lon',
                                                     y='lat',
                                                     u='u',
                                                     v='v',
                                                     transform = ccrs.PlateCarree(),
                                                    ax=mapa)
mapa.gridlines(draw_labels=True)
mapa.coastlines()
plt.show()

结果...

在 streamplot 文档中,x 和 y 数据的数组只有一个要求:均匀分布的严格递增数组以制作网格,因为它们是一维数组。

当经度数据在 [0,360] 范围内时,streamplot 函数似乎无法在 cartopy 地图上正确放置/绘制流线。

这是预期的行为还是 streamplot 和 cartopy 有问题?

谢谢!

python latitude-longitude cartopy
1个回答
0
投票

从你的报价:

It seems that streamplot function cannot place/draw correctly streamlines over a cartopy map when longitude data is in [0,360] range...
,你已经知道了。

我可以通过下面的一些编码和输出图来确认。

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

noproj = projection=ccrs.PlateCarree()
shift90E = projection=ccrs.PlateCarree(central_longitude=90)
shift180 = projection=ccrs.PlateCarree(central_longitude=180)
shift90W = projection=ccrs.PlateCarree(central_longitude=-90)

# Creating dataset
w = 180
h = 90
# Domains of X,Y: (-180, 180), (-90, 90)
# Domains of X,Y are chosen to comply with ability to plot
#  successfully with Cartopy.
Y, X = np.mgrid[-h:h:100j, -w:w:100j]
U = -1 - X**2 + Y
V = 1 + X - Y**2
#speed = np.sqrt(U**2 + V**2)

fig = plt.figure(figsize=[10, 6])

def ax_plot(index, use_project, title):
    ax = fig.add_subplot(2,2,index, projection = use_project)
    ax.streamplot(X,Y,U,V, density=[0.8, 0.8],transform=noproj,linewidth=0.6,minlength=0.2,arrowstyle='->')
    ax.set_extent([-180,180, -90,90], crs=noproj)
    ax.coastlines(resolution='110m', alpha=0.3)
    ax.gridlines(draw_labels=["bottom", "left"])
    ax.set_title(title)

ax_plot(1, noproj, "Zero-meridian-centered")
ax_plot(2, shift90E, "Centered at 90E longitude")
ax_plot(3, shift180, "Dateline-centered")
ax_plot(4, shift90W, "Centered at 90W longitude")
plt.show()

在经度域 (-180, 180) 中使用适当的数据,任何经度偏移的投影上的所有图都是好的。

与具有经度域(0, 360)的类似数据集进行比较, 就在代码行之后

V = 1 + X - Y**2

添加以下代码

X += 180

运行代码后,我得到了这些图。显然,其中一个情节是不可接受的。

© www.soinside.com 2019 - 2024. All rights reserved.