如何在Python中生成4个直方图的平均直方图?
实现四个直方图的平均直方图方案
当然有可行的方法啦!核心思路是先获取前四个直方图的统一分箱区间和对应频率值,然后对每个分箱的频率求平均,最后用这个平均频率和分箱区间绘制第五个直方图。
关键注意点
要保证四个直方图使用完全相同的分箱区间,否则不同分箱的频率无法对应求和,结果没有意义。我们可以复用第一组数据生成的分箱区间给后面三组。
完整实现代码
import numpy as np import matplotlib.pyplot as plt # 生成4组随机数据(优化原代码,用numpy更高效) np.random.seed(42) # 设置随机种子,保证结果可复现 elevations = [np.random.randint(-10000, 10000, size=100) for _ in range(4)] # 绘制前4个直方图,同时保存分箱区间和频率 plt.figure(1) n1, bins, _ = plt.hist(elevations[0], bins=20, label='Elevations1') plt.legend() plt.figure(2) n2, _, _ = plt.hist(elevations[1], bins=bins, label='Elevations2') # 复用bins保证分箱一致 plt.legend() plt.figure(3) n3, _, _ = plt.hist(elevations[2], bins=bins, label='Elevations3') plt.legend() plt.figure(4) n4, _, _ = plt.hist(elevations[3], bins=bins, label='Elevations4') plt.legend() # 计算每个分箱的平均频率 avg_frequency = (n1 + n2 + n3 + n4) / 4 # 绘制平均直方图 plt.figure(5) # 计算分箱中心位置,让柱状图居中显示 bin_centers = (bins[:-1] + bins[1:]) / 2 # 绘制柱状图,宽度与原直方图分箱宽度一致 plt.bar(bin_centers, avg_frequency, width=np.diff(bins), alpha=0.7, color='orange', label='Average Histogram') plt.xlabel('Elevation') plt.ylabel('Average Frequency') plt.title('Average of 4 Elevation Histograms') plt.legend() plt.show()
代码细节解释
- 数据生成优化:用
np.random.randint替代原代码的循环写法,更简洁高效;设置np.random.seed能让每次运行生成的随机数据一致,方便调试和复现结果。 - 保存直方图参数:
plt.hist会返回三个值:n(每个分箱的频率)、bins(分箱区间数组)、patches(图形元素)。我们只需要前两个,并且复用第一组的bins给后面三组,确保所有直方图的分箱规则完全相同。 - 平均频率计算:直接对四个频率数组求和后除以4,就能得到每个分箱的平均频率值。
- 平均直方图绘制:用
plt.bar绘制比再次调用plt.hist更直观,因为我们已经有了现成的频率数据;bin_centers让柱状图居中对齐分箱区间,width=np.diff(bins)保证柱状图宽度和原直方图分箱宽度一致,视觉上更统一。
内容的提问来源于stack exchange,提问作者NEMM2020




