带起点的流图的 Cartopy platecarree 和正交投影问题

Cartopy platecarree and orthographic projection issues for streamplot with starting points

提问人:bproxauf 提问时间:11/11/2020 更新时间:11/11/2020 访问量:925

问:

我想使用带有 Cartopy 包的函数 plt.streamplot 将速度场 (u, v) 绘制为(经度、纬度)的函数作为流图,在板-卡里 (lon-lat) 和正交投影中。我希望流图的起点固定,因为我想最终创建一个动画,其中包含一些要素在球体上旋转,流线“锚定”在某处。但是,我在这些预测中遇到了许多问题,下面将进一步详细说明。matplotlib

我使用以下软件包版本:3.7.6、3.2.2、0.18.0Pythonmatplotlibcartopy


为上述投影创建具有和不具有起点的流图的“最小”示例是:

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

# define longitude and latitude grids
nlon, nlat = 48, 24
dlon, dlat = 7.5, 7.5
lons = np.linspace(-180+dlon,180,nlon)
lats = np.linspace(-90,90-dlat,nlat)

# define random velocity fields
np.random.seed(999)
u = np.random.rand(nlat, nlon)
v = np.random.rand(nlat, nlon)

# get indices of latitudes north of the equator and longitudes within +/- 90 deg
ilat_north = np.where(lats >= 0)[0]
ilon = np.where(np.abs(lons) <= 90)[0]

# create a list of 5 starting points at various latitudes aligned at a longitude of 0 deg
start_points = list(zip(list(np.linspace(0,0,5)),list(np.linspace(0,80,5))))

# output plot directory and whether plots should be saved
plot_dir = '/home/proxauf/test_streamplot_cartopy'
save_plots = True

def plot_streamplot(mode, start_points=None, figtitle=None, outname=None, save_plot=False):

    fig = plt.figure()
    if mode == 'mpl-platecarree':
        # a Plate-Carree projection without Cartopy (directly using matplotlib)
        ax = plt.gca()
        ax.streamplot(lons, lats[ilat_north], u[ilat_north,:], v[ilat_north,:], start_points=start_points)
    elif 'cartopy' in mode:
        if mode == 'cartopy-platecarree':
            # a Plate-Carree projection with Cartopy
            ax = plt.subplot(projection=ccrs.PlateCarree())
            ax.streamplot(lons, lats[ilat_north], u[ilat_north,:], v[ilat_north,:], start_points=start_points, transform=ccrs.PlateCarree())
        elif mode == 'cartopy-orthographic0':
            # an orthographic projection with a latitudinal inclination of 0 deg with Cartopy
            # restrict longitudes to +/- 90 deg, otherwise an error occurs (outside of projection area)
            ax = plt.subplot(projection=ccrs.Orthographic(central_longitude=0,central_latitude=0))
            ax.streamplot(lons[ilon], lats[ilat_north], u[ilat_north[:,None],ilon[None,:]], v[ilat_north[:,None], ilon[None,:]], start_points=start_points, transform=ccrs.PlateCarree())
        if mode == 'cartopy-orthographic90':
            # an orthographic projection with a latitudinal inclination of 90 deg with Cartopy
            ax = plt.subplot(projection=ccrs.Orthographic(central_longitude=0,central_latitude=90))
            ax.streamplot(lons, lats[ilat_north], u[ilat_north,:], v[ilat_north,:], start_points=start_points, transform=ccrs.PlateCarree())
    if 'platecarree' in mode:
        ax.set_xlim(-180,180)
        ax.set_ylim(-90,90)
    ax.set_aspect('equal')
    if 'cartopy' in mode:
        # draw gridlines with label for visual orientation
        ax.gridlines(draw_labels=True)
    if start_points is not None:
        # plot starting points for the streamplot
        for i in start_points:
            if 'cartopy' in mode:
                ax.plot(i[0],i[1],marker='o',transform=ccrs.PlateCarree())
            else:
                ax.plot(i[0],i[1],marker='o')
    fig.suptitle(figtitle)
    if save_plot:
        # save the plot and close it
        plt.savefig('%s/%s' % (plot_dir, outname))
        plt.close()

# create and save streamplots for different projections, with and without starting points
plot_streamplot(mode='mpl-platecarree', start_points=None, figtitle='mpl-platecarree, without start points', outname='test_streamplot_mpl_pc_sp_no.png', save_plot=save_plots)
plot_streamplot(mode='cartopy-platecarree', start_points=None, figtitle='cartopy-platecarree, without start points', outname='test_streamplot_cartopy_pc_sp_no.png', save_plot=save_plots)
plot_streamplot(mode='cartopy-orthographic0', start_points=None, figtitle='cartopy-orthographic0, without start points', outname='test_streamplot_cartopy_ortho0_sp_no.png', save_plot=save_plots)
plot_streamplot(mode='cartopy-orthographic90', start_points=None, figtitle='cartopy-orthographic90, without start points', outname='test_streamplot_cartopy_ortho90_sp_no.png', save_plot=save_plots)
plot_streamplot(mode='mpl-platecarree', start_points=start_points, figtitle='mpl-platecarree, with start points', outname='test_streamplot_mpl_pc_sp_yes.png', save_plot=save_plots)
plot_streamplot(mode='cartopy-platecarree', start_points=start_points, figtitle='cartopy-platecarree, with start points', outname='test_streamplot_cartopy_pc_sp_yes.png', save_plot=save_plots)
plot_streamplot(mode='cartopy-orthographic0', start_points=start_points, figtitle='cartopy-orthographic0, with start points', outname='test_streamplot_cartopy_ortho0_sp_yes.png', save_plot=save_plots)
plot_streamplot(mode='cartopy-orthographic90', start_points=start_points, figtitle='cartopy-orthographic90, with start points', outname='test_streamplot_cartopy_ortho90_sp_yes.png', save_plot=save_plots)

下面是这个最小示例创建的输出。

案例 1:没有起点的 Mpl-Plate-Carree:工作正常:

Mpl-Plate-Carree without starting points

案例 2:没有起点的 Cartopy-Plate-Carrie:工作正常:

Cartopy-Plate-Carree without starting points

案例 3:没有起点的 Cartopy-Orthographic-0:工作正常 (?),但高纬度被切断:

Cartopy-Orthographic-0

案例 4:没有起点的 Cartopy-Orthographic-90:工作正常:

Cartopy-Orthographic-90 without starting points

案例 5:Mpl-Plate-Carree 与起点:工作正常:

Mpl-Plate-Carree with starting points

案例 6:带起点的 Cartopy-Plate-Carree:未显示两个起点的两条流线:

Cartopy-Plate-Carree with starting points

案例 7:Cartopy-Orthographic-0,起点:未显示数据(无流线、起点等):

enter image description here

案例 8:Cartopy-Orthographic-90,起点:仅显示北半球的一部分,流线似乎不正确:

enter image description here


摘要:案例 6、7 和 8(Cartopy Plate-Carree/Orthographic-0deg-inclination/Orthographic-90deg-inclination projections)给出了意想不到的、可能不正确的输出。有人可以向我解释为什么这些情节看起来像那样吗?我是否误解了我应该给出的输入?

小问题:如果我想为正交投影设置轴限制(例如,0 度倾角的纬度限制为 [-90,+90] 度,90 度倾角的纬度限制为 [0, +90] 度,以及经度限制),例如假设我只绘制 30 度以上的数据,这是如何工作的? 或者不起作用,我假设(因为他们不知道投影)。如果需要通过ax.set_extent完成此操作,我需要在那里设置哪些经度和纬度限制?ax.set_xlimax.set_ylim

python matplotlib cartopy 地图投影

评论


答: 暂无答案