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
相关产品推荐
相关产品推荐

