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

Matplotlib hist2d:面向对象风格下如何让颜色条显示计数

解决Matplotlib OOP风格热力图颜色条不匹配计数的问题

问题根源

过程式调用中,plt.hist2d()返回的QuadMesh对象会被plt.colorbar()自动关联,包含了热力图的计数数据、颜色映射和归一化规则。而你手动创建的ScalarMappable没有绑定hist2d的实际计数范围,导致颜色条无法对应真实的计数数值。

修正后的单热力图OOP代码

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

x1 = np.random.normal(size=1000)
y1 = np.random.normal(size=1000)
fig, ax1 = plt.subplots(1, 1)
cmap = mpl.cm.plasma

# 获取hist2d返回的QuadMesh对象,它包含了正确的颜色映射和计数范围
counts, xedges, yedges, im = ax1.hist2d(x1, y1, cmap=cmap, bins=30)

# 将QuadMesh对象传入colorbar,自动生成匹配的颜色条
fig.colorbar(im, ax=ax1)
plt.show()

扩展:绘制两个并排热力图

如果需要实现两个并排的热力图,只需调整子图布局,分别处理每个子图的QuadMesh对象即可:

import numpy as np
import matplotlib as mpl
import matplotlib.pyplot as plt

# 生成两组测试数据
x1 = np.random.normal(size=1000)
y1 = np.random.normal(size=1000)
x2 = np.random.normal(loc=2, size=1000)
y2 = np.random.normal(loc=2, size=1000)

cmap = mpl.cm.plasma
# 创建1行2列的子图布局
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(12, 5))

# 绘制第一个热力图并添加对应颜色条
_, _, _, im1 = ax1.hist2d(x1, y1, cmap=cmap, bins=30)
ax1.set_title('数据集1')
fig.colorbar(im1, ax=ax1)

# 绘制第二个热力图并添加对应颜色条
_, _, _, im2 = ax2.hist2d(x2, y2, cmap=cmap, bins=30)
ax2.set_title('数据集2')
fig.colorbar(im2, ax=ax2)

# 自动调整子图间距
plt.tight_layout()
plt.show()

额外说明

如果需要让两个热力图共享同一颜色范围(便于对比),可以手动定义归一化规则并复用:

from matplotlib.colors import Normalize

# 先计算两组数据的最大计数,统一颜色范围
counts1, _, _, _ = ax1.hist2d(x1, y1, bins=30)
counts2, _, _, _ = ax2.hist2d(x2, y2, bins=30)
max_count = max(counts1.max(), counts2.max())
norm = Normalize(vmin=0, vmax=max_count)

# 绘制时传入统一的norm
_, _, _, im1 = ax1.hist2d(x1, y1, cmap=cmap, bins=30, norm=norm)
_, _, _, im2 = ax2.hist2d(x2, y2, cmap=cmap, bins=30, norm=norm)

# 可以只添加一个共享颜色条
fig.colorbar(im1, ax=[ax1, ax2], orientation='horizontal', pad=0.1)

内容的提问来源于stack exchange,提问作者G.F. Lima

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 07:11:04