以下行
a1, b1, _ = plt.hist(df['y'], bins='auto')
a2, b2 = np.histogram(df['y'], bins='auto')
print(a1 == a2)
print(b1 == b2)
等同于a1
的所有值等于a2
的值,b1
和b2
然后我单独使用pyplot
创建一个地块(使用bins=auto
should use the same np.histogram()
function):
plt.hist(df['y'], bins='auto')
plt.show()
然后我尝试实现相同的直方图,但是我自己调用np.histogram()
并将结果传递给plt.hist()
,但我得到一个空白的直方图:
a2, b2 = np.histogram(df['y'], bins='auto')
plt.hist(a2, bins=b2)
plt.show()
从我理解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
这只是一个分辨率问题,我的情节似乎太小了,两端的尖峰都无法正确渲染。放大允许它们显示。
答案 0 :(得分:7)
您假设plt.hist
可以区分包含计数值的数组和包含要计数值的数组。
然而,事情并非如此,当您将计数传递给plt.hist
时,它会计算它们并将它们放在提供的箱中。这可能导致空的直方图,但也会导致奇怪的直方图。
因此,虽然plt.hist
和numpy.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)
但是,您可以使用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')