matplotlib 如何让多个子图共享同一个 colorbar

多个子图共享一个colorbar需统一vmin/vmax并绑定到figure:先计算全局极值,绘图时显式传入;最后用fig.colorbar(im, ax=axes.tolist())一次性创建,确保刻度准确对应各图数据。

多个子图共享一个 colorbar,关键在于把 colorbar 绑定到整个 figure 而非单个 axes,并确保所有子图使用相同的 normalization(如 vmin/vmax)和 colormap。

统一设置归一化范围

所有子图必须用相同的 vminvmax,否则 colorbar 刻度无法准确对应各图数据。推荐显式指定,而不是依赖自动缩放:

  • 先计算所有子图数据的全局最小/最大值(例如 np.min([data1, data2, data3])
  • 绘图时统一传入:imshow(data, vmin=vmin_all, vmax=vmax_all, cmap='viridis')

  • 避免用 plt.colorbar() 在每个子图上调用——这会生成多个独立 colorbar

plt.colorbar() 指定父 axes 或 figure

在所有子图绘制完成后,调用一次 plt.colorbar(),并传入 mappable(通常是最后一个 imshow 返回的对象)和 ax 参数控制位置:

  • 让 colorbar 横跨整个 figure 底部:plt.colorbar(im, ax=axes, shrink=0.8, aspect=40)axes 是包含所有子图的 ndarray)
  • 更灵活的方式是用 fig.colorbar() 并指定 locationfractionfig.colorbar(im, ax=axes.tolist(), location='right', shrink=0.6)
  • ax=axes.tolist() 告诉 colorbar 参考全部子图的布局,从而自动调整尺寸和位置

手动控制 colorbar 位置(可选进阶)

当默认布局不理想(比如子图太窄、colorbar 被截断),可用 plt.axes() 创建独立 colorbar axes:

  • 例如:cax = plt.axes([0.85, 0.15, 0.02, 0.7])([left, bottom, width, height])
  • 再调用:plt.colorbar(im, cax=cax)
  • 注意:此时要确保 im 是某个子图的 mappable 对象,且所有子图仍共用同一 vmin/vmax

不复杂但容易忽略的是归一化一致性——只要数据范围统一、colorbar 绑定到整体布局,共享就自然成立。