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

自定义xarray分面绘图colorbar指定位置的实现方法

xarray结合cartopy自定义分面图colorbar位置

需求说明

使用xarray结合cartopy绘制地理数据分面图时,需要将colorbar水平放置在子图网格的第5行,从第2列开始排布,参考效果如下:
自定义colorbar位置参考示意图
初始可复现代码如下:

import cartopy.crs as ccrs
import numpy as np
import xarray as xr
# 生成随机测试数据
annual=xr.DataArray(np.random.randint(1,100,(41,186,469)), dims=("year","y","x"), coords={"year":np.arange(1981,2022),
                                                                                         "y":np.linspace(29,38,186),
                                                                                         "x":np.linspace(-10,10,469)})
# 初始绘图代码
proj=ccrs.PlateCarree()
fig=annual.plot(col="year",col_wrap=10, cmap="Spectral", vmin=1, vmax=105,
                subplot_kws={"projection":proj, "aspect":2.5})
# 设置标题样式
years=[f"Year = {i}" for i in range(1981,2022)]

for ax, year in zip(fig.axes.flatten(), years):
    ax.set_title(year,fontsize=15)
    ax.set_extent([-10, 10, 29, 38])
    ax.coastlines(linewidth=0.5)
    
fig.cbar.ax.tick_params(labelsize=30)
fig.cbar.set_label(label='Label', size=30, weight='bold')

实现方案

xarray分面绘图默认生成的colorbar位置固定,无法直接通过参数指定到目标网格位置,需要先关闭默认colorbar,再基于子图网格坐标手动创建cbar轴实现自定义布局,修改后的完整代码如下:

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

# 生成测试数据
annual=xr.DataArray(np.random.randint(1,100,(41,186,469)), dims=("year","y","x"), coords={"year":np.arange(1981,2022),
                                                                                         "y":np.linspace(29,38,186),
                                                                                         "x":np.linspace(-10,10,469)})
proj=ccrs.PlateCarree()
# 关键参数:add_colorbar=False 关闭默认生成的colorbar
g = annual.plot(col="year",col_wrap=10, cmap="Spectral", vmin=1, vmax=105,
                subplot_kws={"projection":proj, "aspect":2.5},
                add_colorbar=False)

# 原有子图样式设置
years=[f"Year = {i}" for i in range(1981,2022)]
for ax, year in zip(g.axes.flatten(), years):
    ax.set_title(year,fontsize=15)
    ax.set_extent([-10, 10, 29, 38])
    ax.coastlines(linewidth=0.5)

# 调整子图间距,为colorbar预留合适显示空间
plt.subplots_adjust(bottom=0.12, hspace=0.35, wspace=0.05)

# 基于已有子图的位置,计算colorbar放置区域的边界坐标
# 子图按行优先从上到下、从左到右排列:第1行索引0-9,第2行10-19,第3行20-29,第4行30-39,第5行(最下方)索引40
x_left = g.axes[31].get_position().x0  # 取第4行第2列的左边界,作为cbar的左起点(和第2列对齐)
x_right = g.axes[39].get_position().x1 # 取第4行第10列的右边界,作为cbar的右终点(和第10列对齐)
y_bottom = g.axes[40].get_position().y0 # 取第5行的下边界,作为cbar的下边界
y_top = g.axes[40].get_position().y1 # 取第5行的上边界,作为cbar高度参考

# 创建colorbar专属轴,高度设为单张子图高度的70%,避免和子图标题重叠
cbar_ax = g.fig.add_axes([x_left, y_bottom, x_right - x_left, (y_top - y_bottom)*0.7])
# 取第一个子图的绘图映射对象,生成水平colorbar
mappable = g.axes[0].collections[0]
cbar = g.fig.colorbar(mappable, cax=cbar_ax, orientation='horizontal')

# 设置colorbar样式
cbar.ax.tick_params(labelsize=12)
cbar.set_label(label='Label', size=15, weight='bold')

plt.show()

关键说明

  • 必须在调用plot()时传入add_colorbar=False,否则默认colorbar会占用布局空间,导致自定义位置对齐偏差
  • 直接通过已有子图的get_position()方法获取坐标,不需要手动估算数值,可以保证colorbar和子图网格完美对齐
  • 可以根据自己的显示需求,调整subplots_adjust的间距参数、cbar轴的高度比例、字体大小等样式

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 06:27:18