直方图Matplotlib


107

所以我有一个小问题。我有一个scipy数据集,该数据集已经是直方图格式,因此我具有了bin的中心以及每个bin的事件数。现在如何绘制直方图。我只是尝试做

bins, n=hist()

但这不是那样。有什么建议吗?

Answers:


239
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()

在此处输入图片说明

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

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

如果您使用的是自定义(非恒定)箱,则可以使用传递计算宽度np.diff,将宽度传递到,ax.bar并使用ax.set_xticks来标记箱边缘:

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()

在此处输入图片说明


有没有办法将垃圾箱边缘传递到条形图的x轴?
CMCDragonkai '16

@CMCDragonkai:plt.barwidth参数可以接受类似数组的对象(而不是标量)。因此,您可以使用width = np.diff(bins)代替width = 0.7 * (bins[1] - bins[0])
unutbu

但是width设置本身只能设置条的宽度,对吗?我说的是x轴标签(也就是说,我想看到实际的容器边缘是x轴上的标签)。它应该类似于plt.hist工作原理。
CMCDragonkai

2
@CMCDragonkai:您可以ax.set_xticks用来设置xlabels。我在上面添加了一个示例来说明我的意思。
unutbu

22

如果您不想要条形图,可以这样绘制:

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()

直方图


6
您也可以使用ax.step
塔卡斯韦尔2014年

12

我知道这不能回答您的问题,但是当我搜索matplotlib直方图解决方案时,我总是最终会在此页面上结束,因为histogram_demo从matplotlib示例库页面中删除了简单方法。

这是一个解决方案,不需要numpy导入。我只导入numpy来生成x要绘制的数据。它依赖于函数hist而不是@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')

在此处输入图片说明

还要查看matplotlib画廊matplotlib示例


“这里是一个解决方案,不需要numpy” –代码导入的第一行numpy :)
Martin R.

2
@MartinR。这只是生成要绘制的数据。参见第4-6行。不使用numpy。
tommy.carstensen

6

如果您愿意使用pandas

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

27
如果您打算建议使用pandas,则可能应该包括指向其站点的链接,以及一个详细的示例来说明发生了什么。
塔卡斯韦尔2014年

0

我认为这可能对某人有用。

令我烦恼的是Numpy的直方图函数(尽管我很高兴有这样做的理由),它返回了每个bin的边缘,而不是bin的值。尽管这对于浮点数有意义,浮点数可以位于一个区间内(即,中心值没有太大意义),但在处理离散值或整数(0、1、2等)时,这不是理想的输出。特别是,从np.histogram返回的bin的长度不等于计数/密度的长度。

为了解决这个问题,我使用了np.digitize来量化输入,并返回离散数量的bin,以及每个bin的计数分数。您可以轻松地进行编辑以获得计数的整数。

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.