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

如何对Matplotlib直方图中的概率分布值进行归一化处理?

同图绘制归一化累积与非累积直方图的解决方案

问题原因

你当前使用density=True参数得到的是概率密度直方图,该模式下要求的是所有bin的面积总和为1,而非bin高度≤1。当bin宽度较小时,概率密度 = 单bin频率 / bin宽度的计算结果自然会出现大于1的情况,这是非累积曲线y轴超标的核心原因。

解决方案

如果你需要让累积、非累积曲线共用0~1范围的y轴,可以将非累积直方图改为频率归一化,即单bin数值为「该bin样本数 / 总样本数」,所有非累积bin高度之和为1,和累积分布的y轴范围完全匹配。

实现时可以通过weights参数给每个样本设置统一权重1/总样本数,同时关闭density参数即可,修改后可运行代码如下:

import matplotlib.pyplot as plt

n_bins = 20
x = [
 0.0051055006412772065,
 0.09770815865459548,
 0.20666651037049322,
 0.5433266733820051,
 0.5717169069724539,
 0.5421114013759187,
 0.4994941193115986,
 0.4391978276380223,
 0.3673067648294034,
 0.3150259778098451,
 0.4072059689437963,
 0.5781929593356039,
 0.6494934859266276,
 0.620882081680377,
 0.5845829440637116,
 0.515705471234385] 

# 统一设置每个样本的权重为1/总样本数,统计结果直接为频率
weights = [1 / len(x)] * len(x)

fig, ax = plt.subplots(figsize=(10, 5))
# 绘制累积分布
n, bins, patches = ax.hist(x, n_bins, weights=weights, stacked=True, histtype='step',
                           cumulative=True, label='Empirical cumulative')
# 绘制非累积分布
ax.hist(x, bins=bins, weights=weights, stacked=True, histtype='step', cumulative=False, label='Empirical non-cumulative')

ax.legend()
plt.show()

可选方案(保留概率密度)

如果你确实需要保留非累积的概率密度含义,可以设置双y轴分别展示两个曲线:左侧y轴对应累积分布(范围0~1),右侧y轴对应非累积概率密度,两者互不干扰。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.18 13:45:03