You need to enable JavaScript to run this app. matplotlib多不同范围子图如何设置全局统一colorbar范围
优惠活动
大模型
产品
解决方案
定价
更多

matplotlib多不同范围子图如何设置全局统一colorbar范围

matplotlib多子图共用全局范围colorbar的实现方法

问题出现的核心机制

  • 循环绘制散点图时,plt.scatter()默认会根据当前子图输入的颜色值,自动计算颜色映射的数值上下限(vmin/vmax)。
  • 最后调用plt.colorbar()时,接口会默认读取当前活动坐标轴(即循环结束后最后绘制的巴西子图)的颜色映射配置,自然就只采用了巴西区域的温度范围。俄罗斯的低温数据远低于这个范围,全部被映射到色阶的最高值,看起来和高温数据配色完全一致。

具体修改步骤

  1. 绘图循环启动前,计算全量数据的全局数值范围,避免手动硬编码数值,适配后续数据变动:
    # 提取所有温度数据的全局最小、最大值
    temp_min = df['Temperature'].min()
    temp_max = df['Temperature'].max()
    
  2. 每次循环绘制散点图时,强制所有散点使用同一套全局上下限做颜色映射:
    在原有plt.scatter()调用中追加vmin、vmax参数:
    plt.scatter(
        data['Depth'], data['%TOC'],
        c=data['Temperature'],
        s=50, edgecolors='k',
        vmin=temp_min,
        vmax=temp_max
    )
    
  3. 生成colorbar时,指定绑定所有子图,避免colorbar宽度只匹配最后一个子图的高度,出现比例失调:
    将原有cbar = plt.colorbar()修改为:
    # 传入所有子图组成的数组,colorbar会自动适配总高度对齐
    cbar = plt.colorbar(ax=axs)
    cbar.ax.set_ylabel('Temperature, degrees C')
    

可选等价实现方式

如果需要更灵活的颜色映射配置,可以在绘图前手动初始化全局归一化对象,所有散点图共用同一个对象即可,和上面传vmin/vmax的效果完全一致:

from matplotlib.colors import Normalize
# 初始化全局统一的归一化配置
global_norm = Normalize(vmin=df['Temperature'].min(), vmax=df['Temperature'].max())

# 循环内调用scatter时,直接传入norm参数即可
plt.scatter(..., norm=global_norm)

修改后的完整可运行代码

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

core_list = ['Russia', 'Brazil']
core_depth = [0, 2, 4, 6, 8, 10]
lo = [-33, 28]
hi = [10, 38]
df = pd.DataFrame([], columns = ['Location', 'Depth', '%TOC', 'Temperature'])

# 填充测试数据
for ii, name in enumerate(core_list):
    for jj in core_depth:
        df.loc[len(df.index)] = [name, jj, (np.random.randint(1, 20))/10, np.random.randint(lo[ii], hi[ii])]

# 提前计算全局温度范围
temp_min = df['Temperature'].min()
temp_max = df['Temperature'].max()

# 绘制子图
fig, axs = plt.subplots(nrows = 1, ncols = 2, sharey = True)
for nn, name in enumerate(core_list):
    core_mask = df['Location'] == name
    data = df.loc[core_mask]
    plt.sca(axs[nn])
    # 传入统一的vmin/vmax
    plt.scatter(data['Depth'], data['%TOC'], c = data['Temperature'], s = 50, edgecolors = 'k',
                vmin=temp_min, vmax=temp_max)
    axs[nn].set_xlabel('%TOC')
    plt.text(1.25*min(data['%TOC']), 1.75, name)
    if nn == 0:
        axs[nn].set_ylabel('Depth')

# 绑定所有子图生成colorbar
cbar = plt.colorbar(ax=axs)
cbar.ax.set_ylabel('Temperature, degrees C')
plt.show()

运行上述代码后,colorbar的范围会完整覆盖从俄罗斯最低的零下三十余度到巴西最高的近四十度的全区间,俄罗斯的低温点会正确映射到冷色色阶,巴西的高温点映射到暖色色阶,不会再出现配色错位的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.28 13:36:09