在matplotlib中让多个子图共享colorbar,需统一vmin/vmax或Normalize实例,用fig.colorbar(im, ax=axes)绑定同一mappable,并通过shrink、aspect或cax精细控制位置。

在 matplotlib 中让多个子图共享同一个 colorbar,关键在于将 colorbar 绑定到一个统一的 mappable(如 imshow、pcolormesh 等返回的对象),并手动指定其位置和范围。不能直接对每个子图分别调用 plt.colorbar(),否则会生成多个独立 colorbar。
使用 fig.colorbar() 并传入统一的 mappable
最常用且推荐的方式是:先绘制所有子图,确保它们使用相同的归一化(norm)和 colormap(cmap),然后选取其中一个子图的绘图对象(mappable)作为 colorbar 的依据,用 fig.colorbar(mappable, ax=...) 添加 colorbar,并通过 ax 参数控制其布局位置。
- 所有子图必须使用相同的
vmin和vmax(或共用一个matplotlib.colors.Normalize实例),否则 colorbar 刻度与图像不匹配 - 用
fig.colorbar(..., ax=[ax1, ax2, ...])可让 colorbar 自动适配多个子图的布局(适用于竖排/横排子图) - 若需精细控制位置(如放在整个 figure 右侧),可配合
plt.axes()手动添加 colorbar 轴
示例:2×2 子图共享右侧 colorbar
以下代码创建四个子图,共享同一 colorbar 放在右侧:
import matplotlib.pyplot as plt import numpy as npfig, axes = plt.subplots(2, 2, figsize=(8, 6)) data = [np.random.randn(10, 10) + i for i in range(4)] # 四组不同均值的数据
统一 vmin/vmax(根据全部数据范围)
vmin, vmax = min(d.min() for d in data), max(d.max() for d in data)
绘制每个子图,复用相同 cmap 和 norm
im = None for i, (ax, d) in enumerate(zip(axes.flat, data)): im = ax.imshow(d, cmap='viridis', vmin=vmin, vmax=vmax) ax.set_title(f'Plot {i+1}')
添加共享 colorbar(绑定到 im,作用于整个 fig)
fig.colorbar(im, ax=axes, shrink=0.6, aspect=20)
plt.tight_layout() plt.show()
进阶:colorbar 独立于子图区域(自定义位置)
当需要把 colorbar 放在 figure 边缘且不干扰子图时,可手动创建 colorbar 轴:
- 用
plt.axes([left, bottom, width, height])定义 colorbar 的位置(归一化坐标) - 再调用
fig.colorbar(im, cax=cax),其中cax是手动创建的轴 - 适合复杂布局,比如多列子图+单个横向 colorbar
注意事项
-
colorbar 刻度与图不一致:检查是否所有子图都显式设置了
vmin/vmax;建议用Normalize(vmin=..., vmax=...)实例统一传入 -
colorbar 太长/太短:调整
shrink(缩放比例)或aspect(宽高比),或改用cax手动定位 -
子图间距被 colorbar 挤压:调用
plt.tight_layout(rect=[0, 0, 0.85, 1])为 colorbar 预留右侧空间(数值为 [left, bottom, right, top])










