построение гистограмм, чьи высоты баров составляют 1 в matplotlib - PullRequest
70 голосов
/ 05 октября 2010

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

plt.hist(myarray, normed=True)

, а также:

plt.hist(myarray, normed=1)

, но ни один из вариантов не создает ось y из [0, 1], так что высота столбцов суммы гистограммы1. Я хотел бы создать такую ​​гистограмму - как я могу это сделать?

спасибо!

Ответы [ 4 ]

181 голосов
/ 06 мая 2013

Если вы хотите, чтобы сумма всех баров была равна единице, взвесьте каждый бин на общее количество значений:

weights = np.ones_like(myarray)/float(len(myarray))
plt.hist(myarray, weights=weights)

Надеюсь, это поможет, хотя тема довольно старая ...

42 голосов
/ 05 октября 2010

Было бы более полезно, если бы вы представили более полный рабочий (или в данном случае нерабочий) пример.

Я попробовал следующее:

import numpy as np
import matplotlib.pyplot as plt

x = np.random.randn(1000)

fig = plt.figure()
ax = fig.add_subplot(111)
n, bins, rectangles = ax.hist(x, 50, density=True)
fig.canvas.draw()
plt.show()

Это действительно приведет кгистограмма гистограммы с осью Y, которая идет от [0,1].

Далее, согласно документации hist (то есть ax.hist? из ipython), я думаю, что сумма тоже хорошая:

*normed*:
If *True*, the first element of the return tuple will
be the counts normalized to form a probability density, i.e.,
``n/(len(x)*dbin)``.  In a probability density, the integral of
the histogram should be 1; you can verify that with a
trapezoidal integration of the probability density function::

    pdf, bins, patches = ax.hist(...)
    print np.sum(pdf * np.diff(bins))

Попытка после команд выше:

np.sum(n * np.diff(bins))

Я получаю возвращаемое значение 1.0, как и ожидалось.Помните, что normed=True не означает, что сумма значений на каждом столбце будет равна единице, а интеграл по столбцам равен единице.В моем случае np.sum(n) вернул примерно 7.2767.

17 голосов
/ 27 февраля 2013

Я знаю, что этот ответ слишком поздно, учитывая, что вопрос датирован 2010 годом, но я столкнулся с этим вопросом, поскольку сам столкнулся с аналогичной проблемой.Как уже говорилось в ответе, normed = True означает, что общая площадь под гистограммой равна 1, но сумма высот не равна 1. Однако для удобства физической интерпретации гистограммы я хотел бы сделать одинс суммой высот, равной 1.

Я нашел подсказку в следующем вопросе - Python: гистограмма с площадью, нормализованной к чему-то другому, чем 1

Но я не былв состоянии найти способ сделать бары, имитирующие функцию histtype = "step" hist ().Это отвлекло меня от: Matplotlib - пошаговая гистограмма с уже собранными данными

Если сообщество сочтет это приемлемым, я хотел бы предложить решение, которое объединяет идеи из обоих вышеупомянутых постов.

import matplotlib.pyplot as plt

# Let X be the array whose histogram needs to be plotted.
nx, xbins, ptchs = plt.hist(X, bins=20)
plt.clf() # Get rid of this histogram since not the one we want.

nx_frac = nx/float(len(nx)) # Each bin divided by total number of objects.
width = xbins[1] - xbins[0] # Width of each bin.
x = np.ravel(zip(xbins[:-1], xbins[:-1]+width))
y = np.ravel(zip(nx_frac,nx_frac))

plt.plot(x,y,linestyle="dashed",label="MyLabel")
#... Further formatting.

Это прекрасно сработало для меня, хотя в некоторых случаях я заметил, что самый левый или самый правый столбец гистограммы не закрывается при касании самой нижней точки Y-ось.В таком случае добавление элемента 0 в начале или конце y привело к необходимому результату.

Просто подумал, что поделюсь своим опытом.Спасибо.

10 голосов
/ 18 июля 2015

Вот еще одно простое решение с использованием метода np.histogram().

myarray = np.random.random(100)
results, edges = np.histogram(myarray, normed=True)
binWidth = edges[1] - edges[0]
plt.bar(edges[:-1], results*binWidth, binWidth)

Вы действительно можете проверить, что общая сумма до 1, с помощью:

> print sum(results*binWidth)
1.0
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...