使用Scipy绘制skewnorm时曲线幅值异常偏低的问题
解决偏态正态分布拟合曲线与直方图幅值不匹配的问题
问题核心是直方图默认统计量和PDF的量纲不一致:
- 直方图默认展示每个区间的样本频数(数量)
skewnorm.pdf()输出的是概率密度值,其积分和为1,数值范围远小于频数
只要调整直方图的归一化模式,就能让两者完美匹配,以下是修正后的完整代码:
from scipy import stats import matplotlib.pyplot as plt import numpy as np data = [ 10, 10, 11, 10, 11, 11, 10, 10, 15, 15, 14, 18, 11, 10, 11, 13, 13, 10, 13, 16 , 16, 15, 11, 16, 12, 11, 17, 13, 11, 14, 12, 11, 10, 12, 11, 12, 10, 12, 10, 12 , 11, 11, 11, 12, 15, 11, 12, 12, 10, 12, 10, 10, 11, 11, 14, 10, 11, 10, 17, 10 , 15, 10, 11, 11, 10, 9, 12, 11, 13, 12, 12, 11, 11, 16, 15, 21, 11, 11, 11, 13 , 11, 12, 10, 21, 10, 13, 10, 10, 13, 13, 10, 18, 13, 13, 11, 14, 10, 14, 13, 11 , 10, 12, 15, 9, 10, 9, 16, 14, 15, 11, 10, 11, 10, 11, 12, 12, 12, 12, 10, 10 , 10, 11, 13, 11, 19, 11, 15, 13, 13, 11, 10, 13, 10, 10, 10, 12, 10, 10, 18, 12 , 12, 13, 11, 17, 10, 11, 10, 14, 12, 12, 14, 10, 15, 10, 10, 12, 12, 11, 10, 25 , 11, 13, 10, 11, 12, 12, 12, 17, 12, 11, 10, 11, 24, 10, 10, 10, 13, 10, 11, 12 , 10, 12, 12, 11, 24, 11, 15, 11, 13, 13, 12, 11, 10, 11, 10, 12, 10] X = np.linspace(min(data), max(data), num=200) # 拟合偏态正态分布参数并计算PDF值 params = stats.skewnorm.fit(data) pdf = stats.skewnorm.pdf(X, *params) fig, ax = plt.subplots() # 关键改动:添加density=True,将直方图归一化为概率密度 ax.hist(data, bins=25, density=True, alpha=0.6, label='样本直方图') ax.plot(X, pdf, 'r-', linewidth=2, label='拟合偏态正态分布') # 优化图表可读性 ax.set_xlabel('数值') ax.set_ylabel('概率密度') ax.set_title('样本数据与拟合偏态正态分布对比') ax.legend() fig.savefig("test.png") plt.show()
可选方案:如果要展示频数而非概率密度
如果需要保持直方图的频数统计模式,可以通过样本总数乘以区间宽度来缩放PDF曲线:
n, bins, patches = ax.hist(data, bins=25, alpha=0.6, label='样本直方图') bin_width = bins[1] - bins[0] # 缩放PDF以匹配频数幅值 ax.plot(X, pdf * len(data) * bin_width, 'r-', linewidth=2, label='拟合偏态正态分布')
内容的提问来源于stack exchange,提问作者Robert
相关产品推荐
相关产品推荐

