plt.hist()vs np.histogram() - 意外结果

时间:2017-10-09 22:37:16

标签: python numpy matplotlib histogram binning

以下行

a1, b1, _ = plt.hist(df['y'], bins='auto')
a2, b2 = np.histogram(df['y'], bins='auto')

print(a1 == a2)
print(b1 == b2)

等同于a1的所有值等于a2的值,b1b2

的值相同

然后我单独使用pyplot创建一个地块(使用bins=auto should use the same np.histogram() function):

plt.hist(df['y'], bins='auto')
plt.show()

enter image description here

然后我尝试实现相同的直方图,但是我自己调用np.histogram()并将结果传递给plt.hist(),但我得到一个空白的直方图:

a2, b2 = np.histogram(df['y'], bins='auto')
plt.hist(a2, bins=b2)
plt.show()

enter image description here

从我理解plt.hist(df['y'], bins='auto')的工作方式来看,我创建的这两个图应该完全相同 - 为什么我的方法不能使用Numpy

修改

继续下面的@ MSeifert回答,我相信

counts, bins = np.histogram(df['y'], bins='auto')

bins是每个bin的起始值列表,counts是每个bin中相应的值数。如上面的直方图所示,这应该会产生近乎完美的正态分布,但是,如果调用print(counts, bins) the result of counts表明第一个和最后一个分箱的实际数量相当于~11,000。为什么这不会反映在直方图中 - 为什么两条尾部都没有两个大的尖峰?

编辑2

这只是一个分辨率问题,我的情节似乎太小了,两端的尖峰都无法正确渲染。放大允许它们显示。

1 个答案:

答案 0 :(得分:7)

您假设plt.hist可以区分包含计数值的数组和包含要计数值的数组

然而,事情并非如此,当您将计数传递给plt.hist时,它会计算它们并将它们放在提供的箱中。这可能导致空的直方图,但也会导致奇怪的直方图。

因此,虽然plt.histnumpy.histogram的工作方式相同,但您无法将从numpy.histogram获取的数据传递给plt.hist,因为这会计算值的计数(不是您的期望):

import numpy as np
import matplotlib.pyplot as plt

%matplotlib notebook

f, ax = plt.subplots(1)
arr = np.random.normal(10, 3, size=1000)
cnts, bins = np.histogram(arr, bins='auto')
ax.hist(cnts, bins=bins)

enter image description here

但是,您可以使用bar绘图来虚拟化numpy.histogram获得的直方图:

f, (ax1, ax2) = plt.subplots(2)
cnts, bins = np.histogram(arr, bins='auto')
ax1.bar(bins[:-1] + np.diff(bins) / 2, cnts, np.diff(bins))
ax2.hist(arr, bins='auto')

enter image description here