막대의 높이가 matplotlib에서 1이되도록 히스토그램을 플로팅하려면 어떻게해야합니까?


85

matplotlib를 사용하여 벡터에서 정규화 된 히스토그램을 플로팅하고 싶습니다. 다음을 시도했습니다.

plt.hist(myarray, normed=True)

만큼 잘:

plt.hist(myarray, normed=1)

그러나 어느 옵션도 [0, 1]에서 y 축을 생성하지 않아 히스토그램의 막대 높이의 합이 1이됩니다. 이러한 히스토그램을 생성하고 싶습니다. 어떻게해야합니까?


5
나는 이것이 오래되었다는 것을 알고 있지만, 향후 참조 및이 페이지를 방문하는 모든 사람을 위해 이러한 종류의 축 스프레드를 "확률 밀도"축이라고합니다!
ChristineB

답변:


48

더 완전한 작업 (또는이 경우에는 작동하지 않는) 예제를 제시하면 더 도움이 될 것입니다.

다음을 시도했습니다.

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.


3
네, 그것은 확률 밀도 그래프입니다. 저는 그가 확률 질량 그래프를 원한다고 생각합니다.
NoName

200

모든 막대의 합이 같은 단위가되도록하려면 총 값 수로 각 빈에 가중치를 부여합니다.

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

스레드가 꽤 오래되었지만 도움이되기를 바랍니다.

Python 2.x 참고 사항 : float()나누기 연산자 중 하나에 캐스팅을 추가하십시오. 그렇지 않으면 정수 나누기로 인해 0이됩니다.


8
좋은 대답입니다. myArray의 파이썬 경우주의 array_likeNumPy와 배열이 아니라 당신이 캐스트에 필요 len(myarray)float.
cmh

3
또한 myarray가 다차원이고 myarray [0 ,:]과 같은 하나의 차원 만 사용하는 경우 len (myarray)를 np.size (myarray [0 ,:])로 바꿀 수 있습니다. 같은 길. (그렇지 않으면, 객체가 호출되지 않습니다 말한다.)
ChristineB

22

나는이 질문이 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 축의 가장 낮은 지점을 터치해도 닫히지 않는다는 것을 알아 차 렸지만 이것은 저에게 훌륭하게 작동했습니다. 이러한 경우 구걸 또는 y 끝에 요소 0을 추가하면 필요한 결과를 얻을 수 있습니다.

내 경험을 공유하겠다고 생각했습니다. 감사합니다.


plt.hist에서도 normed = True가 필요하다고 생각합니다. 또한 Python 3에서는 list (zip (...))를 사용해야합니다.
Sebastian Schmitz

11

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
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.