首页 > 解决方案 > 如何标准化 matplotlib 直方图中的概率分布值?

问题描述

我试图在同一个图上显示累积和非累积分布。

fig, ax = plt.subplots(figsize=(10, 5))

n, bins, patches = ax.hist(x, n_bins, density=True, stacked=True, histtype='step',
                           cumulative=True, label='Empirical cumulative')

# Overlay a non-cumulative histogram.
ax.hist(x, bins=bins, density=True, stacked=True, histtype='step', cumulative=False, label='Empirical non-cumulative')

plt.show()

曲线看起来不错,Empirical cumulative值不超过 1。但是,Empirical non-cumulative曲线的 Y 值高于 1。如何标准化它们?

更新:

样本数据:

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] 

请看橙色曲线。

在此处输入图像描述

在此处输入图像描述

标签: pythonmatplotlibhistogram

解决方案


probability使用而不是创建直方图的最简单方法probability density是使用 seaborn 的sns.histplot(.... stat='probability').

要使用标准 matplotlib 模拟这一点,您可以手动计算所有值。例如:

import matplotlib.pyplot as plt
import numpy as np

n_bins = 20
x = np.random.normal(0, 1, (1000, 3))
bin_edges = np.linspace(x.min(), x.max(), n_bins + 1)
bin_values = np.array([np.histogram(x[:, i], bins=bin_edges)[0] for i in range(x.shape[1])])
cum_values = bin_values.cumsum(axis=1).cumsum(axis=0)
cum_values = cum_values / cum_values.max()

fig, ax = plt.subplots(figsize=(10, 5))
prev = 0
for c in cum_values:
    plt.step(np.append(bin_edges, bin_edges[-1]), np.concatenate([[0], c, [prev]]))
    prev = c[-1]

ax.set_prop_cycle(None)
prev = 0
for c in cum_values:
    c = np.diff(c)
    plt.step(np.append(bin_edges, bin_edges[-1]), np.concatenate([[0], c, [c[-1], prev]]), ls='--')
    prev = c[-1]

plt.show()

带有概率而不是密度的直方图

如果您只有一个发行版,stacked=True则没有什么区别。代码会更简单:

import matplotlib.pyplot as plt
import numpy as np

n_bins = 20
x = np.random.normal(0, 1, 1000)
bin_edges = np.linspace(x.min(), x.max(), n_bins + 1)
bin_values = np.histogram(x, bins=bin_edges)[0]
cum_values = bin_values.cumsum()
cum_values = cum_values / cum_values.max()

fig, ax = plt.subplots(figsize=(10, 5))
plt.step(np.append(bin_edges, bin_edges[-1]), np.concatenate([[0], cum_values, [0]]))

ax.set_prop_cycle(None)
c = np.diff(cum_values)
plt.step(np.append(bin_edges, bin_edges[-1]), np.concatenate([[0], c, [c[-1], 0]]), ls='--')

plt.show()

推荐阅读