如何用Matplotlib绘制2D分箱散点值均值的直方图/六边形图?
用Matplotlib绘制分箱内z值均值的六边形图/二维直方图
嘿,这个需求确实很常见,Matplotlib完全可以不用繁琐的手动分箱来实现!我给你两种方案的具体实现方法:
一、六边形分箱图(Hexbin Plot)
Matplotlib的hexbin()函数其实原生就支持自定义分箱内的聚合方式,默认是统计样本数量,但我们可以通过参数指定计算z值的均值:
核心思路:
- 用
C参数传入你的z数组 - 通过
reduce_C_function指定聚合函数为np.mean(默认是求和)
- 用
代码示例:
import matplotlib.pyplot as plt import numpy as np # 生成模拟数据(替换成你的真实数据) np.random.seed(42) x = np.random.randn(10000) y = np.random.randn(10000) z = x * y + np.random.randn(10000) # z值和x、y相关 fig, ax = plt.subplots(figsize=(8, 6)) # 绘制六边形分箱图,以z的均值着色 hb = ax.hexbin(x, y, C=z, reduce_C_function=np.mean, gridsize=30, cmap='viridis') # 添加颜色条并标注 cb = fig.colorbar(hb, ax=ax) cb.set_label('Mean of z values') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_title('Hexbin Plot: Mean z per Hexagon') plt.show()
这样就直接得到了每个六边形分箱内z值的均值着色图,比手动循环分箱简洁太多!
二、二维矩形直方图(2D Histogram)
如果想要矩形分箱的版本,我们可以结合numpy.histogram2d先计算分箱内的z值总和与样本数量,再推导均值,最后用pcolormesh绘制:
核心思路:
- 用
np.histogram2d同时计算分箱的样本计数(counts)和z值的总和(sums,通过weights=z实现) - 计算均值:
means = sums / counts,注意处理空分箱(除以0的情况,用np.nan_to_num避免报错)
- 用
代码示例:
import matplotlib.pyplot as plt import numpy as np # 同样用上面的模拟数据 np.random.seed(42) x = np.random.randn(10000) y = np.random.randn(10000) z = x * y + np.random.randn(10000) fig, ax = plt.subplots(figsize=(8, 6)) # 计算分箱的计数和z值总和 counts, x_edges, y_edges = np.histogram2d(x, y, bins=30) sums, _, _ = np.histogram2d(x, y, bins=30, weights=z) # 计算均值,替换空分箱的NaN为0(或你想要的默认值) means = np.nan_to_num(sums / counts) # 绘制二维直方图 im = ax.pcolormesh(x_edges, y_edges, means.T, cmap='viridis') # 添加颜色条 cb = fig.colorbar(im, ax=ax) cb.set_label('Mean of z values') ax.set_xlabel('x') ax.set_ylabel('y') ax.set_title('2D Histogram: Mean z per Bin') plt.show()
这里要注意pcolormesh需要转置均值数组(means.T),因为histogram2d返回的数组形状是(len(x_edges)-1, len(y_edges)-1),和绘图的轴对应需要转置。
两种方法都能完美实现你的需求,不用手动写复杂的分箱逻辑,希望对你有帮助!
内容的提问来源于stack exchange,提问作者kuropan
相关产品推荐
相关产品推荐

