построение гистограмм, высота баров которых равна 1 в matplotlib
Я хотел бы построить нормализованную гистограмму из вектора с помощью matplotlib. Я попробовал следующее:
plt.hist(myarray, normed=True)
а также:
plt.hist(myarray, normed=1)
но ни один из вариантов не создает ось y из [0, 1] такой, что высоты баров гистограммы суммируются до 1. Я хотел бы создать такую гистограмму - как я могу это сделать?
спасибо!
4 ответов:
было бы более полезно, если бы вы представили более полный рабочий (или в данном случае нерабочий) пример.
я попробовал следующий:
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.
Если вы хотите, чтобы сумма всех баров была равна единице, вес каждого Бина по общему количеству значений:
weights = np.ones_like(myarray)/float(len(myarray)) plt.hist(myarray, weights=weights)надеюсь, что это поможет, хотя нить довольно старая...
Я знаю, что этот ответ слишком поздно, учитывая, что вопрос датирован 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 достигло необходимого результата.
просто подумал, что поделюсь своим опытом. Спасибо.
вот еще одно простое решение, используя
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
Comments