为数据点相对较少的直方图选择 bin
Choice of bins for histograms with relatively few datapoints
考虑一个具有多个 histograms in matplotlib 的图,如下所示:
#! /usr/bin/env python3
import matplotlib.pyplot as plt
import random
# Use the same seed for reproducibility.
random.seed(10586)
data1 = [random.gauss(1e-4, 3e-2) for _ in range(10**3)] + [0.3]
data2 = [random.gauss(1e-2, 3e-3) for _ in range(10**3)] + [0.4]
data3 = [0.2]
if __name__ == '__main__':
plt.xlim(xmin=0, xmax=0.8)
plt.yscale('log')
n1, bins1, patches1 = plt.hist(data1, bins='auto', alpha=0.6)
n2, bins2, patches2 = plt.hist(data2, bins='auto', alpha=0.6)
n3, bins3, patches3 = plt.hist(data3, bins='auto', alpha=0.6)
bin_options = ['auto', 'fd', 'doane', 'scott', 'rice', 'sturges', 'sqrt']
plt.show()
然而,第三个数据集只有一个数据点,
所以当我们使用 plt.hist(data3, bins='auto')
我们得到一个横跨 x-range 的长条,
并且再也看不到它的值为 0.2:
(这在只有一个数据点时最为明显,
但这是一个问题,例如也有两三个。)
避免这种情况的一种方法是 re-use 另一个数据集的 bin。
例如,对于 plt.hist(data3, bins=bins1)
,
我们可以看到 data3
就好了:
但是,如果我们通过 bins=bins2
使用另一个数据集,
箱子太窄了,我们根本看不到 data3
:
我们怎样才能保证点比较少的直方图是可见的,
但仍然在 x-axis?
上看到它的价值
为了确保您能看到条形图,即使它太窄而无法构成一个像素,您也可以给它一个边缘颜色,
import matplotlib.pyplot as plt
import random
random.seed(10586)
data2 = [random.gauss(1e-2, 3e-3) for _ in range(10**3)] + [0.4]
plt.xlim(0, 0.8)
plt.yscale('log')
n2, bins2, patches2 = plt.hist(data2, bins='auto', alpha=0.6, edgecolor="C0")
plt.show()
或者使用 histtype="stepfilled"
创建一个多边形,因为不管怎么说,单个条形图无法与那么多 bin 区分开来,
n2, bins2, patches2 = plt.hist(data2, bins='auto', alpha=0.6, histtype="stepfilled")
后者还具有遵守 alpha 的优点,否则由于条的重叠而看不到。此外,绘制单个形状应该比绘制大约 1000 个条更快。
考虑一个具有多个 histograms in matplotlib 的图,如下所示:
#! /usr/bin/env python3
import matplotlib.pyplot as plt
import random
# Use the same seed for reproducibility.
random.seed(10586)
data1 = [random.gauss(1e-4, 3e-2) for _ in range(10**3)] + [0.3]
data2 = [random.gauss(1e-2, 3e-3) for _ in range(10**3)] + [0.4]
data3 = [0.2]
if __name__ == '__main__':
plt.xlim(xmin=0, xmax=0.8)
plt.yscale('log')
n1, bins1, patches1 = plt.hist(data1, bins='auto', alpha=0.6)
n2, bins2, patches2 = plt.hist(data2, bins='auto', alpha=0.6)
n3, bins3, patches3 = plt.hist(data3, bins='auto', alpha=0.6)
bin_options = ['auto', 'fd', 'doane', 'scott', 'rice', 'sturges', 'sqrt']
plt.show()
然而,第三个数据集只有一个数据点,
所以当我们使用 plt.hist(data3, bins='auto')
我们得到一个横跨 x-range 的长条,
并且再也看不到它的值为 0.2:
(这在只有一个数据点时最为明显, 但这是一个问题,例如也有两三个。)
避免这种情况的一种方法是 re-use 另一个数据集的 bin。
例如,对于 plt.hist(data3, bins=bins1)
,
我们可以看到 data3
就好了:
但是,如果我们通过 bins=bins2
使用另一个数据集,
箱子太窄了,我们根本看不到 data3
:
我们怎样才能保证点比较少的直方图是可见的, 但仍然在 x-axis?
上看到它的价值为了确保您能看到条形图,即使它太窄而无法构成一个像素,您也可以给它一个边缘颜色,
import matplotlib.pyplot as plt
import random
random.seed(10586)
data2 = [random.gauss(1e-2, 3e-3) for _ in range(10**3)] + [0.4]
plt.xlim(0, 0.8)
plt.yscale('log')
n2, bins2, patches2 = plt.hist(data2, bins='auto', alpha=0.6, edgecolor="C0")
plt.show()
或者使用 histtype="stepfilled"
创建一个多边形,因为不管怎么说,单个条形图无法与那么多 bin 区分开来,
n2, bins2, patches2 = plt.hist(data2, bins='auto', alpha=0.6, histtype="stepfilled")
后者还具有遵守 alpha 的优点,否则由于条的重叠而看不到。此外,绘制单个形状应该比绘制大约 1000 个条更快。