如何在单个画布中创建共享一个颜色条的两个2D直方图?
解决Matplotlib并排2D直方图显示异常问题
问题分析
你遇到的左侧子图空白、右侧子图重复显示的问题,核心原因是未正确指定直方图的绘图子图轴:
- 直接对
axs[0]重新赋值会覆盖初始创建的子图对象,导致原轴被丢弃 - 调用
plt.hist2d时未指定ax参数,所有绘图默认绑定到当前活动子图(最后创建的那个)
修正后的完整代码
import numpy as np import matplotlib.pyplot as plt import pandas as pd xlabels = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'] ylabels = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'] df=pd.read_csv("Mod4Data.csv", nrows = 366) # 日期格式转换与特征提取 df["Date"]=pd.to_datetime(df["Day"]) df["Day of Week"]=df["Date"].dt.dayofweek df['week_of_year'] = df['Date'].dt.strftime('%W').astype(float) df['Month'] = df['Date'].dt.month # 数据类型转换 df['Value1'] = df['Value1'].astype(float) df['Value2'] = df['Value2'].astype(float) # 创建1行2列的子图布局,共享坐标轴保证视觉一致性 fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(18, 10), sharey=True, sharex=True) # 绘制第一个2D直方图,指定到ax1子图 hist1 = ax1.hist2d(df["Day of Week"], df["week_of_year"], bins=[7,52], weights=df["Value1"], vmin=1000, vmax=20000) ax1.set_title("Value 1 Amounts") # 绘制第二个2D直方图,指定到ax2子图 hist2 = ax2.hist2d(df["Day of Week"], df["week_of_year"], bins=[7,52], weights=df["Value2"], vmin=1000, vmax=20000) ax2.set_title("Value 2 Amounts") # 统一设置坐标轴刻度和标签,避免重复代码 for ax in [ax1, ax2]: ax.set_yticks([2, 6.3348, 10.66, 14.99, 19.32, 23.65, 27.98, 32.31, 36.64, 40.97, 45.3, 49.63], ylabels) ax.set_xticks([0, 1, 2, 3, 4, 5, 6], xlabels, rotation=45) # 添加共享颜色条,让两个子图使用同一色标范围 fig.colorbar(hist1[3], ax=[ax1, ax2], shrink=0.8) plt.tight_layout() plt.show()
关键改动说明
- 指定绘图轴:使用
ax1.hist2d()的方式,确保直方图绘制到对应的子图上,不再覆盖初始子图对象 - 共享坐标轴:通过
sharex=True和sharey=True让两个子图共享刻度,简化设置同时保证视觉统一 - 共享颜色条:提取第一个直方图的颜色映射对象,绑定到两个子图,实现色标范围一致
- 代码优化:用循环批量处理两个子图的刻度设置,减少重复代码
内容的提问来源于stack exchange,提问作者Jen Reif
相关产品推荐
相关产品推荐

