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

Matplotlib散点图跨子图标准化色阶与公共colorbar配置实现

问题根源

你现在的代码会生成两套完全独立的颜色映射规则:Matplotlib的scatter接口默认会拿当前传入的z值数组的最小/最大值,自动计算颜色对应的数值跨度,哪怕两个子图用了一模一样的色卡名字,相同z值的颜色根本对不上。
比如你的示例数据里,左图z值范围是1-4,右图是2-6:z=3在左图是色卡中间色,在右图是偏浅的低数值色,跨图对比完全没有意义。

修正逻辑

要让两个子图的颜色和z值一一对应,只需要给两个散点图用完全相同的数值归一化规则,把色阶的上下边界固定死,不让每个子图自己算范围就行。
具体步骤:

  • 把两组数据的所有z值拼到一起,找全局的最小、最大值,作为统一色阶的两个端点
  • 生成全局通用的归一化对象,调用scatter的时候把这个对象传进去,替代默认的自动范围计算
  • 加统一colorbar的时候,让它自动适配整个子图组的布局,不要挤在某一个子图边上
修正后可直接运行的代码
import numpy as np
import matplotlib.pyplot as plt
import matplotlib.colors as mcolors

# 原始测试数据
vals1 = np.array([[1,1,1],[2,2,4]])
vals2 = np.array([[1,1,2],[2,2,6]])

# 计算全局统一的色阶上下限
all_z = np.concatenate([vals1[:, 2], vals2[:, 2]])
global_norm = mcolors.Normalize(vmin=all_z.min(), vmax=all_z.max())

fig, ax = plt.subplots(1, 2, constrained_layout=True)
# 两个散点图传入完全相同的norm参数,保证色彩映射对齐
g1 = ax[0].scatter(
    x=vals1[:,0], y=vals1[:,1], 
    c=vals1[:,2], cmap='RdBu', 
    norm=global_norm
)
g2 = ax[1].scatter(
    x=vals2[:,0], y=vals2[:,1], 
    c=vals2[:,2], cmap='RdBu', 
    norm=global_norm
)
# 生成跨子图的统一colorbar,指定ax=ax让布局自动适配
fig.colorbar(g1, ax=ax, label='关联z值')
容易踩的坑
  • 别以为用同一个cmap名就够了:映射比例是每个scatter调用独立计算的,和色卡本身没有关系
  • 色阶范围别只拿单组数据算:不然另一组超出范围的z值会被硬塞成色卡的边界极端色,和实际数值对不上
  • 用constrained_layout自动排版的时候,给colorbar加ax=ax参数:不然colorbar会吃掉某一个子图的宽度,让两个子图宽度不一致

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.23 17:15:01