ฉันจะพล็อตฮิสโตแกรมเพื่อให้ความสูงของแท่งรวมเป็น 1 ใน matplotlib ได้อย่างไร


86

ฉันต้องการพล็อตฮิสโตแกรมปกติจากเวกเตอร์โดยใช้ matplotlib ฉันลองทำสิ่งต่อไปนี้:

plt.hist(myarray, normed=True)

เช่นเดียวกับ:

plt.hist(myarray, normed=1)

แต่ทั้งสองตัวเลือกไม่ได้สร้างแกน y จาก [0, 1] ดังนั้นความสูงของแท่งฮิสโตแกรมถึง 1 ฉันต้องการสร้างฮิสโตแกรมแบบนี้ - ฉันจะทำได้อย่างไร?


6
ฉันรู้ว่านี่เป็นเรื่องเก่า แต่สำหรับการอ้างอิงในอนาคต & ใครก็ตามที่เข้าชมหน้านี้การแพร่กระจายของแกนประเภทนี้เรียกว่าแกน "ความหนาแน่นของความน่าจะเป็น"!
ChristineB

คำตอบ:


50

จะเป็นประโยชน์มากขึ้นหากคุณวางตัวอย่างการทำงานที่สมบูรณ์มากขึ้น

ฉันลองทำสิ่งต่อไปนี้:

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()

นี้แน่นอนจะผลิต histogram บาร์กราฟกับแกน 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

201

หากคุณต้องการให้ผลรวมของแท่งทั้งหมดเป็นเอกภาพเท่ากันให้ถ่วงน้ำหนักแต่ละถังด้วยจำนวนค่าทั้งหมด:

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

หวังว่าจะช่วยได้แม้ว่ากระทู้จะค่อนข้างเก่า ...

หมายเหตุสำหรับ Python 2.x: เพิ่มการหล่อfloat()สำหรับตัวดำเนินการตัวใดตัวหนึ่งของการหารมิฉะนั้นคุณจะได้ศูนย์เนื่องจากการหารจำนวนเต็ม


8
คำตอบที่ดี โปรดทราบว่าถ้าเป็น myArray หลามarray_likeมากกว่าอาร์เรย์ numpy คุณจะต้องโยนไปlen(myarray) float
ซม

3
นอกจากนี้หาก myarray มีหลายมิติและคุณใช้เพียงมิติเดียวเช่น myarray [0 ,:] คุณสามารถสลับ len (myarray) ด้วย np.size (myarray [0 ,:]) และจะได้ผล วิธีการเดียวกัน. (มิฉะนั้นจะบอกว่าวัตถุนั้นไม่สามารถเรียกได้)
ChristineB

22

ฉันรู้ว่าคำตอบนี้สายเกินไปเนื่องจากคำถามเป็นวันที่ปี 2010 แต่ฉันเจอคำถามนี้ในขณะที่ฉันกำลังเผชิญกับปัญหาที่คล้ายกัน ตามที่ระบุไว้แล้วในคำตอบ normed = True หมายความว่าพื้นที่ทั้งหมดภายใต้ฮิสโตแกรมมีค่าเท่ากับ 1 แต่ผลรวมของความสูงไม่เท่ากับ 1 อย่างไรก็ตามฉันต้องการเพื่อความสะดวกในการตีความทางกายภาพของฮิสโตแกรมให้สร้าง ด้วยผลรวมของความสูงเท่ากับ 1

ฉันพบคำใบ้ในคำถามต่อไปนี้ - Python: Histogram ที่มีพื้นที่ที่ปรับให้เป็นมาตรฐานเป็นอย่างอื่นที่ไม่ใช่ 1

แต่ฉันไม่สามารถหาวิธีทำให้แท่งเลียนแบบ histtype = "step" feature 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 ได้ผลลัพธ์ที่จำเป็น

แค่คิดว่าฉันจะแบ่งปันประสบการณ์ของฉัน ขอขอบคุณ.


ฉันคิดว่าคุณต้องการ normed = True เช่นกันใน plt.hist นอกจากนี้ใน 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.