Я пытаюсь сделать очень простую гистограмму с помощью matplotlib.pyplot.hist, и, похоже, не удается правильно подсчитать количество значений в каждой ячейке. Вот мой код:

    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) и, аналогично, он считает значение .6 как часть интервала [.5, .6). Я пробовал это и на Spyder, и на Google Colab. Кто-нибудь знает, что происходит? Спасибо!

0
Guillem Pérez-Nadal 1 Сен 2020 в 01:53

2 ответа

Лучший ответ

Проблема в том, что значения попадают как раз на границы бинов. Округление с плавающей запятой может поместить их в предыдущий или следующий лоток. Вам нужны четкие границы бункеров между точками данных. Обратите внимание, что гистограмма 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.1, .1)
        ax.set_title('data between bin boundaries')
    values, bin_bounds, bars = ax.hist(data, bins=bins, alpha=0.3)

    ax.vlines(bin_bounds, 0, 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()

illustrating plot

1
JohanC 31 Авг 2020 в 23:19

Из документации:

Если бункеры - последовательность, она определяет края бункера, включая левый край первого бункера и правый край последнего бункера; в этом случае интервалы могут быть расположены неравномерно. Все, кроме последней (самой правой) корзины, полуоткрыты. Другими словами, если бункеры есть:

[1, 2, 3, 4]

тогда первая ячейка - это [1, 2) (включая 1, но исключая 2), а вторая - [2, 3). Однако последняя ячейка - это [3, 4], которая включает 4.

Поскольку интервалы закрываются - открываются, и .2, и .3 попадают в одну корзину, а .5 и .6 - в другую.

Вы должны исправить ячейки, немного сдвинув границы, чтобы числа не падали на края.

0
89f3a1c 31 Авг 2020 в 23:09