2011-03-16 150 views
88

所以我有一个小问题。我在scipy中已经有一个数据集,它已经是直方图格式,所以我有了bin的中心和每个bin的事件数量。我现在如何绘制直方图。我试着只是做直方图Matplotlib

bins, n=hist() 

,但它不喜欢那个。任何建议?

回答

201
import matplotlib.pyplot as plt 
import numpy as np 

mu, sigma = 100, 15 
x = mu + sigma * np.random.randn(10000) 
hist, bins = np.histogram(x, bins=50) 
width = 0.7 * (bins[1] - bins[0]) 
center = (bins[:-1] + bins[1:])/2 
plt.bar(center, hist, align='center', width=width) 
plt.show() 

enter image description here

的面向对象的界面也很简单:

fig, ax = plt.subplots() 
ax.bar(center, hist, align='center', width=width) 
fig.savefig("1.png") 

如果使用定制(非恒定)箱,你可以通过使用计算出的宽度np.diff,通过宽度以ax.bar并使用ax.set_xticks标记的bin边缘:

import matplotlib.pyplot as plt 
import numpy as np 

mu, sigma = 100, 15 
x = mu + sigma * np.random.randn(10000) 
bins = [0, 40, 60, 75, 90, 110, 125, 140, 160, 200] 
hist, bins = np.histogram(x, bins=bins) 
width = np.diff(bins) 
center = (bins[:-1] + bins[1:])/2 

fig, ax = plt.subplots(figsize=(8,3)) 
ax.bar(center, hist, align='center', width=width) 
ax.set_xticks(bins) 
fig.savefig("/tmp/out.png") 

plt.show() 

enter image description here

+0

有一种方法来传递的bin边缘以条形图的x轴? – CMCDragonkai 2016-09-09 09:54:33

+0

@CMCDragonkai:'plt.bar'的'width'参数可以接受类似数组的对象(而不是标量)。所以你可以使用'width = np.diff(bins)'而不是'width = 0.7 *(bins [1] - bins [0])'。 – unutbu 2016-09-09 14:54:17

+0

但是'width'设置本身只设置了右边栏的宽度?我在谈论x轴标签(这是我想看到实际的bin边缘是x轴上的标签)。它应该与'plt.hist'的工作方式相似。 – CMCDragonkai 2016-09-10 12:22:45

16

如果你不想吧,你可以画出这样的:

import numpy as np 
import matplotlib.pyplot as plt 

mu, sigma = 100, 15 
x = mu + sigma * np.random.randn(10000) 

bins, edges = np.histogram(x, 50, normed=1) 
left,right = edges[:-1],edges[1:] 
X = np.array([left,right]).T.flatten() 
Y = np.array([bins,bins]).T.flatten() 

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

histogram

+4

您也可以使用'ax.step'。 – tacaswell 2014-05-04 21:29:18

5

如果你愿意使用pandas

pandas.DataFrame({'x':hist[1][1:],'y':hist[0]}).plot(x='x',kind='bar') 
+26

如果您打算建议使用'pandas',那么您应该包含一个指向他们网站的链接,以及一个解释发生了什么的更多示例。 – tacaswell 2014-05-04 21:28:41

6

我知道t他不回答你的问题,但是当我搜索matplotlib解决方案到直方图时,我总是在这个页面上结束,因为从matplotlib示例图库页面中删除了简单的histogram_demo

这里是一个解决方案,其不需要numpy进口。我只导入numpy生成要绘制的数据x。它依赖于功能hist,而不是作为answer通过@unutbu功能bar

import numpy as np 
mu, sigma = 100, 15 
x = mu + sigma * np.random.randn(10000) 

import matplotlib.pyplot as plt 
plt.hist(x, bins=50) 
plt.savefig('hist.png') 

enter image description here

还检查了matplotlib gallerymatplotlib examples

+0

“这是一个解决方案,它不需要numpy” - 第一行代码导入numpy :) – 2018-01-25 18:31:37

+0

@Martin R.这只是为了生成要绘制的数据。见第4-6行。没有使用numpy。 – 2018-01-25 18:50:50

+0

我知道,我知道,这不是一个真正的投诉。 – 2018-01-25 19:24:46

0

我认为这可能是有用的人。

与NumPy的直方图功能,我的烦恼(虽然我很欣赏有一个很好的理由),返回每个区间的边缘,而不是仓的价值。然而,这对浮点数是有意义的,它可能位于一个区间内(即中心值不是超有意义的),当处理离散值或整数(0,1,2等)时,这不是所需的输出, 。特别是,从np.histogram返回的bin的长度不等于count/density的长度。

要解决这个问题,我用np.digitize量化的输入,并返回仓的离散数,与计数每个区间的分数一起。您可以轻松编辑以获取整数个计数。

def compute_PMF(data) 
    import numpy as np 
    from collections import Counter 
    _, bins = np.histogram(data, bins='auto', range=(data.min(), data.max()), density=False) 
    h = Counter(np.digitize(data,bins) - 1) 
    weights = np.asarray(list(h.values())) 
    weights = weights/weights.sum() 
    values = np.asarray(list(h.keys())) 
    return weights, values 
#### 

参考文献:

[1] https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html

[2] https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html