使用 Seaborn 计算直方图下的面积

Calculate the area under the histogram with Seaborn

我正在尝试使用此函数计算 seaborn 直方图下的面积(数据已标准化)

sum (np.diff(bins_sns)*values_sns)

获取 bin 的宽度和我使用的高度值

values_sns=[h.get_height()for h in sns.distplot(data).patches]
bins_sns=[h.get_width ()for h in sns.distplot(data).patches]

但它们的长度不同,即 71,48。 这是我得到的错误:ValueError: operands could not be broadcast together with shapes (71,) (​​48,)

如有任何帮助,我们将不胜感激。

这里有几处错误:

  • sns.distplot(data) 创建直方图(连同 kdeplot);在上面的代码中它被调用了两次,所以在同一个地方创建了两个直方图
  • sns.distplot(data) returns 它绘制的 axax 包含一个子图的所有图形元素
  • ax.patches returns 已绘制的所有面片的列表(面片可以是矩形、圆形、闭合曲线……)
  • sns.distplot(data) 不是给定 ax 上的第一个绘制操作时,ax.patches 可以包含之前绘制的元素;特别是调用 sns.distplot(data) 两次会使补丁的数量加倍(在这种情况下似乎绘制了 48 个柱)
  • np.diff(bins_sns) 将包含后续 bin 宽度之间的所有差异。请注意,差异比值少一个(72 个值给出 71 个差异)。由于通常所有 bin 宽度都相等,np.diff(bins_sns) 将全部为零。
  • 要计算总面积,您需要将所有单独的宽度乘以所有单独的高度
import matplotlib.pyplot as plt
import seaborn as sns
import numpy as np

data = np.random.normal(0, 1, 100)
ax = sns.distplot(data)

values_sns = [h.get_height() for h in ax.patches]
bins_sns = [h.get_width() for h in ax.patches]

total_area = sum([height * width for height, width in zip(values_sns, bins_sns)])
# total_area = np.sum(np.array(bins_sns) * np.array(values_sns)) # shorter, faster using numpy
print("total_area:", total_area)  # 1.0