You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

少分箱直方图上绘制平滑泊松/高斯分布曲线的方法

问题背景
  • 有一组服从泊松分布的本底计数数据,绝大多数计数值为0,拟合泊松分布结果如下:
    本底数据直方图与泊松分布拟合
  • 另有一组高计数率放射源数据集,泊松拟合效果正常:
    放射源数据直方图与泊松分布拟合
现有实现代码
mean_values = []
# 计算统计量与绘图
for a in data_arrays:
    dataset = globals()[a]
    cps_vals = dataset[:,1]
    max_cps = int(max(cps_vals))
    mean_name = a +"_mean"
    std_name = a + "_std"
    serr_name = a + "_serr"
    mean = globals()[mean_name] = np.mean(cps_vals)
    globals()[std_name] = np.std(cps_vals,ddof=1)
    globals()[serr_name] = globals()[std_name]/np.sqrt(len(cps_vals))
    print(a,"mean:",globals()[mean_name],"sqrt(mean):",np.sqrt(globals()[mean_name]),"std:",globals()[std_name],"serr:",globals()[serr_name],"sqrt(lambda)/sigma =",np.sqrt(globals()[mean_name])/globals()[std_name])
    
    # 绘制直方图与泊松拟合曲线
    plt.figure()
    bin_edges = np.arange(0, max_cps+1.1, 1)
    histogram = plt.hist(cps_vals,density=True,bins=bin_edges)
    plt.xlabel("Counts Per Second")
    plt.ylabel("Probability of Occurence")
    pops = histogram[0]
    bins = histogram[1]
    
    maxidx = np.argmax(pops)
    maxpop = pops[maxidx]
    maxbin = np.max(bins)
    most_populated_bin = bins[maxidx]
    
    plt.plot(np.arange(0, maxbin), poisson.pmf(np.arange(0,maxbin), 
    np.mean(cps_vals)),c="black")

其中绘制泊松分布曲线的核心代码行:
plt.plot(np.arange(0, maxbin), poisson.pmf(np.arange(0,maxbin), np.mean(cps_vals)),c="black")

遇到的问题

缩小np.arange步长时,泊松曲线出现振铃现象:
缩小步长后的拟合效果1
缩小步长后的拟合效果2
初步推测现象原因是泊松分布仅支持整数计数值作为输入,需要为本底计数生成平滑的高斯曲线,现有输出效果不符合预期。

解决方案

你的判断正确,泊松分布是离散概率分布,仅在非负整数域有定义。向poisson.pmf传入非整数参数时,scipy底层会通过伽马函数计算广义阶乘得到返回值,这类值没有实际概率意义,是导致曲线振铃的直接原因。
可按实际需求选择对应处理方式:

  • 泊松分布本身是离散分布,规范的展示方式是仅在整数计数值位置绘制PMF取值,用散点或柱状图呈现,强行绘制连续平滑曲线不符合离散分布的属性。如果一定要获得平滑的视觉效果,可对整数点上计算得到的PMF值做样条插值,不要直接计算非整数点的泊松PMF。
  • 如果需要绘制高斯近似曲线,注意泊松分布仅在参数λ(即计数均值)足够大(通常要求λ>5)时,才和均值为λ、标准差为√λ的正态分布近似程度较高。本底数据集绝大多数计数值为0,λ远小于5,高斯近似本身就会和实际分布偏差很大。如果仍要绘制,可使用正态分布PDF生成连续曲线上的点,参考代码如下:
from scipy.stats import norm
# 生成200个点的连续x轴,保证曲线平滑
x_smooth = np.linspace(0, max_cps, 200)
# 正态分布参数:位置参数为样本均值,尺度参数为均值的平方根
gauss_curve = norm.pdf(x_smooth, loc=mean, scale=np.sqrt(mean))
plt.plot(x_smooth, gauss_curve, c="black", label="Gaussian Approximation")

补充说明:代码中通过globals()动态创建变量的写法可维护性差,存在变量污染风险,建议改用字典结构存储不同数据集对应的统计量。

内容的提问来源于stack exchange,提问作者Amy M

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 13:27:19