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

使用plt.hist的density=True时直方图面积不为1的疑问

关于matplotlib plt.hist(density=True)的归一化误区解释

文档描述没错,问题出在你的计算方式理解有误。

核心逻辑:density=True 是让直方图总面积归一为1

当设置density=True时,matplotlib会调整每个直方图柱的高度,使得所有柱的高度 × 柱宽度的总和(即直方图的总面积)等于1,以此近似概率密度函数(PDF)。

你的计算错误点

  • 直接用sum(data1):这是对柱的高度求和,完全没考虑每个柱的宽度。bins数量变化时,柱宽度会变,高度也会跟着调整,所以这个求和结果肯定不会是1,还会随bins数量波动。
  • 用np.trapz(data1):你只传入了高度数据data1,np.trapz默认会用步长1计算积分,但实际每个柱的步长(宽度)是bin_edges[i+1] - bin_edges[i],不是1。这种情况下计算的积分自然不是总面积,结果也会随bins变化。

正确的计算方式

调用plt.hist时要捕获返回的三个值:柱高度、柱边缘坐标、绘图对象。然后通过以下两种方式计算总面积,结果会接近1:

import numpy as np
import matplotlib.pyplot as plt

test_dataset = np.random.normal(size=1000)
# 获取直方图的高度、bin边缘
hist_heights, bin_edges, _ = plt.hist(test_dataset, bins=30, density=True)

# 方法1:直接计算每个柱的面积并求和
total_area = np.sum(hist_heights * np.diff(bin_edges))
print("总面积(方法1):", total_area)

# 方法2:用np.trapz,传入bin的中点作为x坐标
bin_midpoints = bin_edges[:-1] + np.diff(bin_edges)/2
total_area_trapz = np.trapz(hist_heights, bin_midpoints)
print("总面积(方法2):", total_area_trapz)

不管bins数量怎么调整,只要数据量足够,这两个计算结果都会接近1,符合density=True的设计逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 22:30:53