【问题标题】:Is there a bug in binning in matplotlib histograms? Or non-randomness of the rvs method in scipy.statsmatplotlib 直方图中的分箱是否存在错误?或者 scipy.stats 中 rvs 方法的非随机性
【发布时间】:2014-01-28 14:51:10
【问题描述】:

以下代码始终生成带有空箱的直方图,即使在样本数量很大的情况下也是如此。空箱似乎具有规则的间距,但与其他普通箱的宽度相同。这显然是错误的——为什么会这样? 似乎 rvs 方法是非随机的,或者 hist binning 过程是箍的。此外,尝试将垃圾箱的数量更改为 50,另一个奇怪的现象出现了。在这种情况下,看起来每个其他 bin 都有与之关联的虚假高计数。

""" An example of how to plot histograms using matplotlib
This example samples from a Poisson distribution, plots the histogram
and overlays the Gaussian with the same mean and standard deviation

"""

from scipy.stats import poisson
from scipy.stats import norm
from matplotlib import pyplot as plt
#import matplotlib.mlab as mlab

EV = 100   # the expected value of the distribution
bins = 100 # number of bins in our histogram
n = 10000
RV = poisson(EV)  # Define a Poisson-distributed random variable

samples = RV.rvs(n)  # create a list of n random variates drawn from that random variable

events, edges, patches = plt.hist(samples, bins, normed = True, histtype = 'stepfilled')  # make a histogram

print events  # When I run this, some bins are empty, even when the number of samples is large

# the pyplot.hist method returns a tuple containing three items. These are events, a list containing
# the counts for each bin, edges, a list containing the values of the lower edge of each bin
# the final element of edges is the value of the high edge of the final bin
# patches, I'm not quite sure about, but we don't need at any rate
# note that we really only need the edges list, but we need to unpack all three elements of the tuple
# for things to work properly, so events and patches here are really just dummy variables

mean = RV.mean()  # If we didn't know these values already, the mean and std methods are convenience
sd = RV.std()     # methods that allow us to retrieve the mean and standard deviation for any random variable

print "Mean is:", mean, " SD is: ", sd

#print edges

Y = norm.pdf(edges, mean, sd)  # this is how to do it with the sciPy version of a normal PDF
# edges is a list, so this will return a list Y with normal pdf values corresponding to each element of edges

binwidth = (len(edges)) / (max(edges) - min(edges))
Y = Y * binwidth
print "Binwidth is:", 1/binwidth
# The above is a fix to "de-normalize" the normal distribution to properly reflect the bin widths

#Q = [edges[i+1] - edges[i] for i in range(len(edges)-1)]
#print Q  # This was to confirm that the bins are equally sized, which seems to be the case.

plt.plot(edges, Y)
plt.show()

【问题讨论】:

    标签: python matplotlib scipy


    【解决方案1】:

    当您的输入数据仅采用整数值(Poisson RV 就是这种情况)并且您的 bin 数量超过此间隔时,预计会出现空 bin。如果是这种情况,您将拥有永远不会捕获样本的垃圾箱和一些将捕获多个间隔样本的垃圾箱。更改 bin 的数量和范围以捕获整数间隔并且间隙消失。

    plt.hist(samples, 
             range=(0,samples.max()),
             bins=samples.max()+1, 
             normed = True, histtype = 'stepfilled')
    

    【讨论】:

    • @Wombat 欢迎来到 Stack Overflow!我很高兴能帮上忙。打印并目视检查样本总是一个好主意 - 这是我做的第一件事,有相同的 headslap 时刻。请务必对好的答案/问题进行投票,如果它解决了您的问题,请接受答案。
    • 这很有帮助!另外值得一提的是,如果这之后还有白线,那是我的情况,因为我也有rwidth=0.9而不是1
    猜你喜欢
    • 2021-01-07
    • 1970-01-01
    • 1970-01-01
    • 2011-04-29
    • 2012-07-03
    • 2021-10-29
    • 1970-01-01
    • 1970-01-01
    • 2013-07-23
    相关资源
    最近更新 更多