Matplotlib中的bin大小(直方图)


Answers:


270

实际上,这很简单:您可以提供一个带有bin边界的列表,而不是bin的数量。它们也可能分布不均:

plt.hist(data, bins=[0, 10, 20, 30, 40, 50, 100])

如果只希望它们均匀分布,则可以使用range:

plt.hist(data, bins=range(min(data), max(data) + binwidth, binwidth))

添加到原始答案

上一行data仅适用于整数填充。正如macrocosme所指出的,对于浮点数,您可以使用:

import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))

20
用np.arange(...)替换range(...)以使其与浮点数一起使用。
macrocosme

6
此处的binwidth是多少?您是否已设置过该值?
UserYmY

1
我相信,在这个例子中binwidth可以通过以下方式找到:(data.max() - data.min()) / number_of_bins_you_want。在+ binwidth可以改变只是1使之成为一个更容易理解的例子。
Jarad

2
除了上述CodingCat出色的解决方案之外,对于浮动数据,如果您希望直方图条形图以整数x线为中心,而不是条形图边界位于x线,请尝试以下调整:bins = np.arange(dmin-0.5, dmax + 0.5 + binwidth,binwidth)
DaveW

3
选项lw = 5, color = "white"或类似的选项在条之间插入白色间隙
PatrickT

13

对于N个仓,仓边缘由N + 1个值的列表指定,其中前N个给出较低仓边缘,而+1给出最后一个仓的较高边缘。

码:

from numpy import np; from pylab import *

bin_size = 0.1; min_edge = 0; max_edge = 2.5
N = (max_edge-min_edge)/bin_size; Nplus1 = N + 1
bin_list = np.linspace(min_edge, max_edge, Nplus1)

请注意,linspace产生从min_edge到max_edge的数组,该数组分为N + 1个值或N个bin


1
请注意,bin包含其下限,不包含其上限,但N + 1(最后一个)bin除外,其中包含两个界限。
lukewitmer '16

4

我猜最简单的方法是计算您拥有的数据的最小值和最大值,然后计算L = max - min。然后L,用所需的箱宽度除(我假设这就是箱大小),然后将该值的上限用作箱数。


正是我的初衷,谢谢。只是想知道是否有更简单的方法,但这似乎很感谢!
山姆·克里默

使用四舍五入,我无法通过这种方法获得四舍五入的bin大小。有人经历过吗?
布拉德·乌拉尼

3

我喜欢事情会自动发生,而垃圾箱却落在“不错的”价值上。以下似乎很好用。

import numpy as np
import numpy.random as random
import matplotlib.pyplot as plt
def compute_histogram_bins(data, desired_bin_size):
    min_val = np.min(data)
    max_val = np.max(data)
    min_boundary = -1.0 * (min_val % desired_bin_size - min_val)
    max_boundary = max_val - max_val % desired_bin_size + desired_bin_size
    n_bins = int((max_boundary - min_boundary) / desired_bin_size) + 1
    bins = np.linspace(min_boundary, max_boundary, n_bins)
    return bins

if __name__ == '__main__':
    data = np.random.random_sample(100) * 123.34 - 67.23
    bins = compute_histogram_bins(data, 10.0)
    print(bins)
    plt.hist(data, bins=bins)
    plt.xlabel('Value')
    plt.ylabel('Counts')
    plt.title('Compute Bins Example')
    plt.grid(True)
    plt.show()

结果以良好的间隔大小间隔包含了间隔。

[-70. -60. -50. -40. -30. -20. -10.   0.  10.  20.  30.  40.  50.  60.]

计算箱直方图


正是我想要的!但是,在某些情况下,由于浮点精度,n_bins被舍入。例如,对于desired_bin_size=0.05min_boundary=0.850max_boundary=2.05计算n_bins成为int(23.999999999999993)其结果在23而不是24,因此一个容器太少。整数转换前的取整对我n_bins = int(round((max_boundary - min_boundary) / desired_bin_size, 0)) + 1
有用

3

我使用分位数来使容器均匀并适合于采样:

bins=df['Generosity'].quantile([0,.05,0.1,0.15,0.20,0.25,0.3,0.35,0.40,0.45,0.5,0.55,0.6,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1]).to_list()

plt.hist(df['Generosity'], bins=bins, normed=True, alpha=0.5, histtype='stepfilled', color='steelblue', edgecolor='none')

在此处输入图片说明


1
好想法。您可以用np.arange(0, 1.01, 0.5)或代替分位数列表np.linspace(0, 1, 21)。没有边缘,但是我知道盒子的面积相等,但X轴的宽度不同?
Tomasz Gandor

2

我遇到了与OP相同的问题(我认为!),但是我无法按照Lastalda指定的方式使其正常工作。我不知道我是否正确解释了这个问题,但是我找到了另一种解决方案(尽管这可能是一种非常糟糕的方法)。

我就是这样的:

plt.hist([1,11,21,31,41], bins=[0,10,20,30,40,50], weights=[10,1,40,33,6]);

这创建了这个:

该图显示了在matplotlib中创建的直方图

因此,第一个参数基本上是“初始化”垃圾箱-我专门创建一个数字,该数字介于我在垃圾箱参数中设置的范围之间。

为了说明这一点,请查看第一个参数([1,11,21,31,41])中的数组和第二个参数([0,10,20,30,40,50]中的'bins'数组:

  • 数字1(从第一个数组开始)介于0到10之间(在“ bins”数组中)
  • 数字11(来自第一个数组)介于11和20之间(在“ bins”数组中)
  • 数字21(从第一个数组开始)介于21到30(在“ bins”数组中)之间,依此类推。

然后,我使用'weights'参数定义每个垃圾箱的大小。这是用于weights参数的数组:[10,1,40,33,6]。

因此0到10 bin的值是10,11到20 bin的值是1,21到30 bin的值是40,依此类推。


3
我认为您对直方图功能的工作原理有一个基本的误解。它期望原始数据。因此,在您的示例中,数据数组应包含0到10之间的10个值,10到20之间的1个值,依此类推。然后,该函数进行求和和绘图。上面的操作是一种解决方法,因为您已经有了总和(然后您可以通过滥用“权重”选项将其插入到图形中)。希望这能消除一些困惑。
CodingCat

-1

对于具有整数x值的直方图,我最终使用

plt.hist(data, np.arange(min(data)-0.5, max(data)+0.5))
plt.xticks(range(min(data), max(data)))

0.5的偏移量使分箱在x轴值上居中。该plt.xticks调用为每个整数添加一个刻度。

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.