Python分布拟合中直方图叠加PDF线不完整的解决咨询
Python分布拟合PDF曲线显示不全问题修复
实际开展基于Python的分布拟合工作时,常出现叠加在直方图上的PDF曲线断档、覆盖范围不全的问题,以下是对应脚本的典型错误点与可直接落地的修复方案:
典型错误溯源
- x轴取值数组错位:原脚本用
np.arange(len(y))生成的数组存放的是样本索引值,并非匹配直方图数值轴的实际数据取值范围,绘制出的PDF曲线x坐标和直方图完全不在同一坐标系下 - 量纲不匹配:绘制直方图时未启用
density=True参数,直方图返回的是原始频数计数,和scipy计算的概率密度分量纲不一致,即便x轴对齐也会出现量级偏差 - PDF缩放逻辑错误:原脚本用索引值x计算PDF的积分面积,推导出来的缩放比例完全偏离真实值,导致曲线高度、位置错位
- 范围过度裁剪:手动将x轴上限设为y的90分位值,直接截断了分布两端的曲线部分
- 参数传递错位:硬编码拆分拟合参数的结构,对不同参数个数的分布(如正态分布无额外形状参数、beta分布有2个形状参数)会出现参数取值错位,导致PDF计算结果偏差
修复操作步骤
- 替换错误的x轴生成逻辑:基于实际数据的取值范围生成连续细网格数组,作为PDF计算的横坐标
- 直方图绘制时显式传入
density=True参数,让直方图纵轴和PDF分量纲天然对齐,省去手动缩放的积分计算环节,减少误差 - 传参时不再硬拆拟合结果,直接将
dist.fit()返回的所有参数解包传入PDF计算函数,适配不同分布的参数结构 - 取消过度的x轴范围裁剪,直接用数据的最小、最大值作为绘图的x轴边界,保证曲线能覆盖全数据区间
- 分箱边界直接基于数据实际范围生成,不用百分位插值的方式生成分箱,避免分箱范围和数据错配
修复后核心绘图代码
# 基于实际数据范围生成分箱 number_of_bins = 30 bin_cutoffs = np.linspace(y.min(), y.max(), number_of_bins) # 绘制直方图,启用密度归一化 h = plt.hist(y, bins=bin_cutoffs, color='0.75', density=True) # 读取拟合效果排名靠前的分布 number_distributions_to_plot = 5 dist_names = results['Distribution'].iloc[0:number_distributions_to_plot] # 生成覆盖全数据范围的连续横坐标 x_plot = np.linspace(y.min(), y.max(), 1000) for dist_name in dist_names: dist = getattr(scipy.stats, dist_name) # 基于原始数据拟合参数 param = dist.fit(y) # 计算全范围的PDF值 pdf_fitted = dist.pdf(x_plot, *param) # 直接绘制匹配量纲的曲线 plt.plot(x_plot, pdf_fitted, label=dist_name, linewidth=2) # 设置匹配全数据范围的坐标轴 plt.xlim(y.min(), y.max()) plt.legend() plt.show()
内容的提问来源于stack exchange,提问作者Case Msee
相关产品推荐
相关产品推荐

