ฮิสโตแกรม Matplotlib


107

ผมจึงมีปัญหาเล็กน้อย ฉันมีชุดข้อมูลใน scipy ที่อยู่ในรูปแบบฮิสโตแกรมแล้วดังนั้นฉันจึงมีศูนย์กลางของถังขยะและจำนวนเหตุการณ์ต่อถัง ตอนนี้ฉันจะพล็อตเป็นฮิสโตแกรมได้อย่างไร ฉันพยายามแค่ทำ

bins, n=hist()

แต่มันไม่เป็นเช่นนั้น ข้อเสนอแนะใด ๆ

คำตอบ:


239
import matplotlib.pyplot as plt
import numpy as np

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
hist, bins = np.histogram(x, bins=50)
width = 0.7 * (bins[1] - bins[0])
center = (bins[:-1] + bins[1:]) / 2
plt.bar(center, hist, align='center', width=width)
plt.show()

ใส่คำอธิบายภาพที่นี่

อินเทอร์เฟซเชิงวัตถุยังตรงไปตรงมา:

fig, ax = plt.subplots()
ax.bar(center, hist, align='center', width=width)
fig.savefig("1.png")

หากคุณใช้ถังขยะแบบกำหนดเอง (ไม่คงที่) คุณสามารถส่งผ่านการคำนวณความกว้างโดยใช้np.diffส่งผ่านความกว้างไปax.barและใช้ax.set_xticksเพื่อติดป้ายกำกับขอบถัง:

import matplotlib.pyplot as plt
import numpy as np

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)
bins = [0, 40, 60, 75, 90, 110, 125, 140, 160, 200]
hist, bins = np.histogram(x, bins=bins)
width = np.diff(bins)
center = (bins[:-1] + bins[1:]) / 2

fig, ax = plt.subplots(figsize=(8,3))
ax.bar(center, hist, align='center', width=width)
ax.set_xticks(bins)
fig.savefig("/tmp/out.png")

plt.show()

ใส่คำอธิบายภาพที่นี่


มีวิธีส่งขอบถังไปยังแกน x ของกราฟแท่งหรือไม่?
CMCDragonkai

@CMCDragonkai: plt.bar's widthพารามิเตอร์สามารถยอมรับอาร์เรย์เหมือนวัตถุ (แทนเกลา) คุณสามารถใช้width = np.diff(bins)แทนwidth = 0.7 * (bins[1] - bins[0]).
unutbu

แต่การwidthตั้งค่าด้วยตัวเองจะกำหนดความกว้างของแถบเท่านั้นใช่หรือไม่? ฉันกำลังพูดถึงเลเบลแกน x (นั่นคือฉันต้องการเห็นขอบถังที่แท้จริงเป็นป้ายกำกับบนแกน x) มันควรจะคล้ายกับวิธีการplt.histทำงาน
CMCDragonkai

2
@CMCDragonkai: คุณสามารถใช้ax.set_xticksเพื่อตั้งค่า xlabels ฉันได้เพิ่มตัวอย่างด้านบนเพื่อแสดงความหมาย
unutbu

22

หากคุณไม่ต้องการแท่งคุณสามารถพล็อตได้ดังนี้:

import numpy as np
import matplotlib.pyplot as plt

mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

bins, edges = np.histogram(x, 50, normed=1)
left,right = edges[:-1],edges[1:]
X = np.array([left,right]).T.flatten()
Y = np.array([bins,bins]).T.flatten()

plt.plot(X,Y)
plt.show()

ฮิสโตแกรม


6
ax.stepนอกจากนี้คุณยังสามารถใช้
tacaswell

12

ฉันรู้ว่าสิ่งนี้ไม่ตอบคำถามของคุณ แต่ฉันมักจะจบลงในหน้านี้เมื่อฉันค้นหาโซลูชัน matplotlib ไปยังฮิสโตแกรมเนื่องจากวิธีง่ายๆhistogram_demoถูกลบออกจากหน้าแกลเลอรีตัวอย่าง matplotlib

นี่คือวิธีแก้ปัญหาซึ่งไม่จำเป็นต้องnumpyนำเข้า ฉันนำเข้าเฉพาะตัวเลขเพื่อสร้างข้อมูลxที่จะลงจุด มันขึ้นอยู่กับฟังก์ชันhistแทนที่จะเป็นฟังก์ชันbarตามคำตอบของ @unutbu

import numpy as np
mu, sigma = 100, 15
x = mu + sigma * np.random.randn(10000)

import matplotlib.pyplot as plt
plt.hist(x, bins=50)
plt.savefig('hist.png')

ใส่คำอธิบายภาพที่นี่

ยังตรวจสอบแกลเลอรี่ matplotlibและตัวอย่าง matplotlib


"นี่คือวิธีแก้ปัญหาที่ไม่ต้องใช้ numpy" - บรรทัดแรกของการนำเข้าโค้ด numpy :)
Martin R.

2
@Martin R. นั่นเป็นเพียงการสร้างข้อมูลที่จะพล็อต ดูบรรทัดที่ 4-6 ไม่มีการใช้ numpy
tommy.carstensen

6

หากคุณต้องการใช้pandas:

pandas.DataFrame({'x':hist[1][1:],'y':hist[0]}).plot(x='x',kind='bar')

27
หากคุณกำลังจะแนะนำให้ใช้pandasคุณควรใส่ลิงก์ไปยังไซต์ของพวกเขาและตัวอย่างอื่น ๆ ที่อธิบายถึงสิ่งที่เกิดขึ้น
tacaswell

0

ฉันคิดว่านี่อาจเป็นประโยชน์สำหรับใครบางคน

ฟังก์ชันฮิสโตแกรมของ Numpy สำหรับความรำคาญของฉัน (แม้ว่าฉันขอขอบคุณที่มีเหตุผลที่ดีสำหรับมัน) ส่งกลับขอบของแต่ละ bin แทนที่จะเป็นค่าของ bin ในขณะที่สิ่งนี้เหมาะสมสำหรับตัวเลขทศนิยมซึ่งสามารถอยู่ภายในช่วงเวลา (กล่าวคือค่าศูนย์ไม่ได้มีความหมายมาก) นี่ไม่ใช่ผลลัพธ์ที่ต้องการเมื่อจัดการกับค่าที่ไม่ต่อเนื่องหรือจำนวนเต็ม (0, 1, 2, ฯลฯ ) . โดยเฉพาะอย่างยิ่งความยาวของถังขยะที่ส่งกลับจาก np.histogram จะไม่เท่ากับความยาวของจำนวน / ความหนาแน่น

เพื่อหลีกเลี่ยงสิ่งนี้ฉันใช้ np.digitize เพื่อหาจำนวนอินพุตและส่งคืนจำนวนถังขยะที่ไม่ต่อเนื่องพร้อมกับเศษส่วนของการนับสำหรับแต่ละถัง คุณสามารถแก้ไขได้อย่างง่ายดายเพื่อรับจำนวนจำนวนเต็ม

def compute_PMF(data)
    import numpy as np
    from collections import Counter
    _, bins = np.histogram(data, bins='auto', range=(data.min(), data.max()), density=False)
    h = Counter(np.digitize(data,bins) - 1)
    weights = np.asarray(list(h.values())) 
    weights = weights / weights.sum()
    values = np.asarray(list(h.keys()))
    return weights, values
####

อ้างถึง:

[1] https://docs.scipy.org/doc/numpy/reference/generated/numpy.histogram.html

[2] https://docs.scipy.org/doc/numpy/reference/generated/numpy.digitize.html

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.