You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何解决Xarray并排绘制带投影子图时单图双色彩条问题?

解决Xarray+Cartopy并排子图投影绘图问题

你的问题核心在于绘图函数和主代码的坐标轴创建逻辑冲突——每次调用plot_avg时,函数内部都会用plt.axes()新建一个坐标轴,直接覆盖/叠加了你主代码里手动创建的子图,导致所有绘图内容挤到同一个区域,同时每个plot调用都生成独立色条,最终出现"一个绘图区带两个色条"的现象。

下面是修改后的完整解决方案:

第一步:重构绘图函数,复用外部传入的坐标轴

把ax作为参数传入函数,让函数在你指定的子图上绘图,而不是自己创建新坐标轴:

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

# 注意:确保Becki色卡已定义(如果是自定义色卡),否则替换为内置色卡如'viridis'
def plot_avg(data, ax, **kwargs):
    # 直接使用传入的子图坐标轴,不再新建
    ax.coastlines(resolution='10m', zorder=3)
    ax.gridlines(color='gray')
    ax.add_feature(cartopy.feature.LAND, zorder=1, facecolor=cartopy.feature.COLORS['land_alt1'])
    
    # 绘制数据,绑定到指定坐标轴
    im = data.plot(
        ax=ax,
        transform=ccrs.PlateCarree(),  # 匹配你的netCDF数据投影(通常是PlateCarree)
        vmin=34.4,
        vmax=35.81,
        levels=17,
        cmap='Becki',
        cbar_kwargs={'shrink': 0.3}
    )
    return im  # 可选:返回图像对象,方便后续统一处理色条

第二步:主代码创建带投影的子图

创建子图时必须指定Cartopy的投影参数(不能用默认的笛卡尔坐标轴),并将每个子图传入绘图函数:

# 创建画布,设置合适的尺寸避免挤压
fig = plt.figure(figsize=(12, 6))

# 第一个子图:指定南极 Orthographic 投影
ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(central_latitude=-90.0))
plot_avg(var1, ax1)
ax1.set_title('Variable 1')  # 可选:添加子图标题

# 第二个子图:使用相同投影保证一致性
ax2 = fig.add_subplot(1, 2, 2, projection=ccrs.Orthographic(central_latitude=-90.0))
plot_avg(var2, ax2)
ax2.set_title('Variable 2')

# 自动调整布局,防止色条和子图重叠
plt.tight_layout()
plt.show()

额外优化:共用色条(可选)

如果想要两个子图共用一个统一色条,可以修改主代码,只让其中一个图生成色条,然后统一添加到画布:

fig = plt.figure(figsize=(12, 6))

ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(central_latitude=-90.0))
im1 = plot_avg(var1, ax1)
ax1.set_title('Variable 1')

ax2 = fig.add_subplot(1, 2, 2, projection=ccrs.Orthographic(central_latitude=-90.0))
# 第二个图不单独生成色条
plot_avg(var2, ax2, cbar_kwargs={'add_colorbar': False})
ax2.set_title('Variable 2')

# 在画布右侧添加统一色条,同时关联两个子图
fig.colorbar(im1, ax=[ax1, ax2], shrink=0.6)

plt.tight_layout()
plt.show()

关键注意事项

  1. 确认你的netCDF数据坐标是PlateCarree投影(大部分气象/海洋数据都是),如果不是,需要修改transform参数匹配数据的实际投影。
  2. 确保Becki色卡可用——如果是自定义色卡,需要提前定义;如果是拼写错误,替换为Matplotlib内置色卡(如'coolwarm'、'viridis')。

内容的提问来源于stack exchange,提问作者ValientProcess

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.14 08:19:39