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

hist2d多行密度图统一色标:未知vmin/vmax的实现难题

问题描述

需要绘制多行hist2d密度图,要求所有子图使用统一的颜色刻度范围,但vmin和vmax无法预先确定,必须先通过计算所有子图的直方图最值,再重新绘制。参考了相关方案但无法适配真实数据,自行编写的代码无法正常运行。

参考示例代码

import numpy as np
import matplotlib.pyplot as plt

fig, axes = plt.subplots(nrows=1, ncols=3)
for ax in axes.flat:
    im = ax.imshow(np.random.random((10,10)), vmin=0, vmax=1)

fig.colorbar(im, ax=axes.ravel().tolist())

plt.show()

问题代码

import matplotlib.pyplot as plt
import numpy as np # 仅用于最小示例,真实文件中不含此导入

# 获取最值
fig, (ax0,ax1) = plt.subplots(nrows = 2, ncols = 1, sharex = True)
colormax = float("-inf")
colormin = float("inf")

h0 = ax0.hist2d(np.random.random(100), np.random.random(100))
colormax = max(h0[0].max(), colormax)
colormin = min(h0[0].min(), colormin)
h1 = ax1.hist2d(np.random.random(200), np.random.random(200))
colormax = max(h1[0].max(), colormax)
colormin = min(h1[0].min(), colormin)
# 开始绘制真实图表(而非仅用于获取最值)
fig, axes = plt.subplots(nrows = 2, ncols = 1, sharex = True, figsize = (6.4,4.8))
i = 0
h = [h0, h1]
for ax in axes.flat:
    im = ax.imshow(h[i], vmin = colormin, vmax = colormax)
    i += 1
fig.colorbar(im, ax= axes.ravel().tolist())
plt.savefig('imshow.debug.png')

问题分析

你的代码核心问题在于:

  • hist2d的返回值是(counts, xedges, yedges, image),直接用ax.imshow(h[i])会错误地把整个返回元组当作图像输入,而非正确的计数数组+边界信息。
  • 第一次绘图只是为了获取最值,没必要实际渲染,直接用np.histogram2d计算计数即可,避免创建多余的图表。

解决方案

正确流程是:

  1. 先对所有数据集计算二维直方图的计数,找到全局的vmin和vmax。
  2. 重新绘制每个子图的hist2d,指定统一的vmin和vmax,可选统一bin边界保证对比一致性。

示例代码:

import matplotlib.pyplot as plt
import numpy as np

# 模拟真实数据集
data_list = [
    (np.random.random(100), np.random.random(100)),
    (np.random.random(200), np.random.random(200))
]

# 第一步:计算所有数据的直方图最值,可选统一bin边界
counts_list = []
colormin = float("inf")
colormax = float("-inf")
# 统一所有子图的bin数量,保证对比公平
bins = 10

for x, y in data_list:
    counts, xedges, yedges = np.histogram2d(x, y, bins=bins)
    counts_list.append((counts, xedges, yedges))
    # 更新全局最值
    colormin = min(counts.min(), colormin)
    colormax = max(counts.max(), colormax)

# 第二步:绘制统一色标的hist2d子图
fig, axes = plt.subplots(nrows=2, ncols=1, sharex=True, figsize=(6.4, 4.8))

for ax, (counts, xedges, yedges) in zip(axes.flat, counts_list):
    # 用hist2d绘制,指定统一的vmin/vmax
    im = ax.hist2d(xedges[:-1], yedges[:-1], weights=counts.flatten(), bins=bins,
                   vmin=colormin, vmax=colormax)
    # 也可以用pcolormesh实现更灵活的控制:
    # im = ax.pcolormesh(xedges, yedges, counts, vmin=colormin, vmax=colormax)

# 添加统一的色条
fig.colorbar(im[3], ax=axes.ravel().tolist())

plt.savefig('hist2d_uniform_color.png')
plt.show()

关键说明

  • 使用np.histogram2d直接计算计数,避免创建多余的图表窗口,效率更高。
  • 统一所有子图的bins参数,确保不同数据集的直方图划分一致,对比更准确。
  • 绘制时通过vmin和vmax强制所有子图使用相同的颜色刻度范围,实现统一色标。
  • 如果需要更灵活的图像控制,可以用pcolormesh替代hist2d,直接传入计数数组和边界。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 23:53:23