问题描述
我正在尝试使用matplotlib.pyplot.hist创建一个非常简单的直方图,而且似乎没有正确地计算每个bin中的值数量。这是我的代码:
import numpy as np
import matplotlib.pyplot as plt
plt.hist([.2,.3,.5,.6],bins=np.arange(0,1.1,.1))
我将间隔[0,1]划分为宽度为.1的区间,所以我应该得到四个高度为1的条形图。但是输出图形仅包含两个高度为2的条形图:正在计算.3值作为[.2,.3)bin的一部分,并且类似地,它会将.6值作为[.5,.6)bin的一部分。我在Spyder和Google Colab上都尝试过。有人知道发生了什么吗?谢谢!
解决方法
问题在于值仅落在垃圾箱的边界上。 Floating point rounding可以将它们放在上一个或下一个垃圾箱中。您需要在数据点之间很好地划分bin边界。请注意,matplotlib的直方图主要用于浮点舍入没有太大影响的连续分布。
以下代码说明了两种情况下发生的情况:
import numpy as np
import matplotlib.pyplot as plt
data = [.2,.3,.5,.6]
fig,axes = plt.subplots(ncols=2,figsize=(12,4))
for ax in axes:
if ax == axes[0]:
bins = np.arange(0,1.1,.1)
ax.set_title('data on bin boundaries')
else:
bins = np.arange(-0.05,.1)
ax.set_title('data between bin boundaries')
values,bin_bounds,bars = ax.hist(data,bins=bins,alpha=0.3)
ax.vlines(bin_bounds,max(values),color='crimson',ls=':')
ax.scatter(data,np.full_like(data,0.5),color='lime',s=30)
ax.set_ylim(0,2.2)
ax.set_yticks(range(3))
plt.show()
,
来自the docs:
如果 bins 是一个序列,则它定义bin边缘,包括第一个bin的左边缘和最后一个bin的右边缘;在这种情况下,垃圾箱的间距可能不相等。除了最后一个(最右边)的垃圾箱外,其他所有垃圾箱都是半开的。换句话说,如果bin是:
[1,2,3,4]
然后,第一个容器是[1,2)(包括1,但不包括2),第二个容器是[2,3]。但是,最后一个bin是[3,4],其中包括4。
因为间隔是封闭打开的,所以.2和.3都落在同一容器中,而.5和.6都落在另一个容器中。
您应该通过稍微移动边界来固定垃圾箱,以免数字落在边缘。