วิธีการลงจุดฮิสโตแกรมโดยใช้ Matplotlib ใน Python พร้อมรายการข้อมูล


103

ฉันกำลังพยายามพล็อตฮิสโตแกรมโดยใช้matplotlib.hist()ฟังก์ชัน แต่ไม่แน่ใจว่าจะทำอย่างไร

ฉันมีรายชื่อ

probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]

และรายชื่อ (สตริง)

ฉันจะทำให้ความน่าจะเป็นเป็นค่า y ของแต่ละแท่งและชื่อเป็นค่า x ได้อย่างไร

คำตอบ:


176

หากคุณต้องการฮิสโตแกรมคุณไม่จำเป็นต้องแนบ 'ชื่อ' ใด ๆ กับค่า x เนื่องจากบนแกน x คุณจะมีถังข้อมูล:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
np.random.seed(42)
x = np.random.normal(size=1000)
plt.hist(x, density=True, bins=30)  # `density=False` would make counts
plt.ylabel('Probability')
plt.xlabel('Data');

ป้อนคำอธิบายภาพที่นี่

คุณสามารถทำให้ฮิสโตแกรมของคุณดูน่าสนใจยิ่งขึ้นด้วยPDFบรรทัดชื่อเรื่องและคำอธิบาย:

import scipy.stats as st
plt.hist(x, density=True, bins=30, label="Data")
mn, mx = plt.xlim()
plt.xlim(mn, mx)
kde_xs = np.linspace(mn, mx, 301)
kde = st.gaussian_kde(x)
plt.plot(kde_xs, kde.pdf(kde_xs), label="PDF")
plt.legend(loc="upper left")
plt.ylabel('Probability')
plt.xlabel('Data')
plt.title("Histogram");

ป้อนคำอธิบายภาพที่นี่

อย่างไรก็ตามหากคุณมีจุดข้อมูลจำนวน จำกัด เช่นใน OP พล็อตแท่งจะเหมาะสมกว่าในการแสดงข้อมูลของคุณ (จากนั้นคุณอาจติดป้ายกำกับกับแกน x):

x = np.arange(3)
plt.bar(x, height=[1,2,3])
plt.xticks(x, ['a','b','c'])

ป้อนคำอธิบายภาพที่นี่


4
จำไว้ว่าไม่มีเครื่องหมายอัฒภาคที่ท้ายบรรทัดใน python!
Toad22222

12
@ Toad22222 นี่คือข้อความที่ตัดตอนมาจากเซลล์โน้ตบุ๊ก Ipython ลองดำเนินการโดยไม่มีเครื่องหมายอัฒภาคและดูความแตกต่าง ข้อมูลโค้ดทั้งหมดที่ฉันโพสต์บน SO ทำงานได้อย่างสมบูรณ์แบบบนคอมพิวเตอร์ของฉัน
Sergey Bushmanov

3
หากคุณสงสัยเกี่ยวกับเซมิโคลอนที่ Sergey ใช้โปรดดูที่นี่และ# 16 ที่นี่สำหรับวิธีการใช้เซมิโคลอนในสมุดบันทึก Jupyter (เดิมคือโน้ตบุ๊ก IPython) เมื่อวางแผนเพื่อระงับข้อความเกี่ยวกับวัตถุพล็อต
Wayne

20

หากคุณยังไม่ได้ติดตั้ง matplotlib เพียงลองใช้คำสั่ง

> pip install matplotlib

นำเข้าไลบรารี

import matplotlib.pyplot as plot

ข้อมูลฮิสโตแกรม:

plot.hist(weightList,density=1, bins=20) 
plot.axis([50, 110, 0, 0.06]) 
#axis([xmin,xmax,ymin,ymax])
plot.xlabel('Weight')
plot.ylabel('Probability')

แสดงฮิสโตแกรม

plot.show()

และผลลัพธ์เป็นดังนี้:

ป้อนคำอธิบายภาพที่นี่


2
plot.axis ([50, 110, 0, 0.06]) 'บรรทัดนั้นไม่มีประโยชน์สำหรับตัวอย่าง นอกจากนี้เนื่องจากเป็นการยากที่จะกำหนดพื้นที่ของพล็อตที่จะแสดงหากข้อมูลของคุณไม่พอดีทั้งหมดคุณอาจสับสนว่าทำไมข้อมูลจึงแสดงไม่ถูกต้อง
typhon04

10

แม้ว่าคำถามดูเหมือนจะเรียกร้องให้วางแผนฮิสโตแกรมโดยใช้matplotlib.hist()ฟังก์ชัน แต่ก็ไม่สามารถทำได้โดยใช้เนื้อหาเดียวกันกับส่วนหลังของคำถามที่ต้องการใช้ความน่าจะเป็นที่กำหนดเป็นค่า y ของแท่งและชื่อที่กำหนด (สตริง) เป็น ค่า x

ฉันสมมติว่ามีรายชื่อตัวอย่างที่สอดคล้องกับความน่าจะเป็นที่กำหนดในการวาดพล็อต พล็อตแท่งเรียบง่ายมีจุดประสงค์สำหรับปัญหา สามารถใช้รหัสต่อไปนี้:

import matplotlib.pyplot as plt
probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]
names = ['name1', 'name2', 'name3', 'name4', 'name5', 'name6', 'name7', 'name8', 'name9',
'name10', 'name11', 'name12', 'name13'] #sample names
plt.bar(names, probability)
plt.xticks(names)
plt.yticks(probability) #This may be included or excluded as per need
plt.xlabel('Names')
plt.ylabel('Probability')

5

นี่เป็นคำถามเก่า แต่ไม่มีคำตอบก่อนหน้านี้ที่กล่าวถึงปัญหาที่แท้จริงกล่าวคือความจริงที่ว่าปัญหานั้นเกิดจากคำถามนั้นเอง

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

ประการที่สองความจริงที่ว่ามีการระบุป้ายกำกับ (ไม่ใช่ช่วงเวลา) โดยปกติจะหมายความว่าความน่าจะเป็นเป็นตัวแปรการตอบสนองที่เป็นหมวดหมู่และการใช้พล็อตแท่งสำหรับการพล็อตฮิสโตแกรมนั้นดีที่สุด (หรือการแฮ็กวิธีการฮิสโตแกรมของไพล็อต) คำตอบของ Shayan Shafiq ระบุรหัส

อย่างไรก็ตามโปรดดูประเด็นที่ 1 ความน่าจะเป็นเหล่านั้นไม่ถูกต้องและการใช้พล็อตแท่งในกรณีนี้เป็น "ฮิสโตแกรม" จะผิดเนื่องจากไม่ได้บอกเล่าเรื่องราวของการแจกแจงแบบไม่แปรผันด้วยเหตุผลบางประการ (บางทีคลาสอาจทับซ้อนกันและการสังเกตจะนับหลาย ครั้ง?) และไม่ควรเรียกพล็อตดังกล่าวว่าฮิสโตแกรมในกรณีนี้

ฮิสโตแกรมเป็นคำจำกัดความที่แสดงถึงการแจกแจงแบบกราฟิกของการแจกแจงของตัวแปรเดียว (ดูhttps://www.itl.nist.gov/div898/handbook/eda/section3/histogra.htm , https://en.wikipedia.org/wiki / ฮิสโตแกรม) และสร้างขึ้นโดยการวาดแท่งขนาดที่แสดงจำนวนหรือความถี่ของการสังเกตในคลาสที่เลือกของตัวแปรที่สนใจ หากตัวแปรถูกวัดในสเกลต่อเนื่องคลาสเหล่านั้นคือ bins (ช่วงเวลา) ส่วนที่สำคัญของขั้นตอนการสร้างฮิสโตแกรมคือการเลือกวิธีการจัดกลุ่ม (หรือเก็บโดยไม่จัดกลุ่ม) ประเภทของการตอบสนองสำหรับตัวแปรหมวดหมู่หรือวิธีการแบ่งโดเมนของค่าที่เป็นไปได้ออกเป็นช่วงเวลา (ที่ที่จะใส่ขอบเขตถังขยะ) เพื่อให้เกิดความต่อเนื่อง ตัวแปรประเภท การสังเกตทั้งหมดควรเป็นตัวแทนและแต่ละข้อสังเกตเพียงครั้งเดียวในพล็อต นั่นหมายความว่าผลรวมของขนาดแท่งควรเท่ากับจำนวนการสังเกตทั้งหมด (หรือพื้นที่ในกรณีที่มีความกว้างตัวแปรซึ่งเป็นวิธีที่ใช้กันน้อยกว่า) หรือถ้าฮิสโตแกรมถูกทำให้เป็นมาตรฐานความน่าจะเป็นทั้งหมดจะต้องรวมกันได้ถึง 1

หากข้อมูลนั้นเป็นรายการของ "ความน่าจะเป็น" ในการตอบสนองกล่าวคือการสังเกตคือค่าความน่าจะเป็น (ของบางสิ่ง) สำหรับแต่ละวัตถุของการศึกษาคำตอบที่ดีที่สุดคือเพียงแค่plt.hist(probability)ใช้ตัวเลือก binning และการใช้ x-label ที่มีอยู่แล้วคือ น่าสงสัย.

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

import matplotlib.pyplot as plt
probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]
plt.hist(probability)
plt.show()

กับผลลัพธ์

ป้อนคำอธิบายภาพที่นี่

matplotlib ในกรณีดังกล่าวมาถึงโดยค่าเริ่มต้นด้วยค่าฮิสโตแกรมต่อไปนี้

(array([1., 1., 1., 1., 1., 2., 0., 2., 0., 4.]),
 array([0.31308411, 0.32380469, 0.33452526, 0.34524584, 0.35596641,
        0.36668698, 0.37740756, 0.38812813, 0.39884871, 0.40956928,
        0.42028986]),
 <a list of 10 Patch objects>)

ผลลัพธ์คือทูเปิลของอาร์เรย์อาร์เรย์แรกมีจำนวนการสังเกตกล่าวคือสิ่งที่จะแสดงเทียบกับแกน y ของพล็อต (รวมได้ถึง 13 จำนวนการสังเกตทั้งหมด) และอาร์เรย์ที่สองคือขอบเขตช่วงเวลาสำหรับ x -แกน.

สามารถตรวจสอบได้ว่ามีระยะห่างเท่ากัน

x = plt.hist(probability)[1]
for left, right in zip(x[:-1], x[1:]):
  print(left, right, right-left)

ป้อนคำอธิบายภาพที่นี่

หรือตัวอย่างเช่นสำหรับ 3 bins (การตัดสินของฉันเรียกร้องให้มีการสังเกตการณ์ 13 ครั้ง) หนึ่งจะได้รับฮิสโตแกรมนี้

plt.hist(probability, bins=3)

ป้อนคำอธิบายภาพที่นี่

ด้วยข้อมูลพล็อต "ด้านหลังบาร์"

ป้อนคำอธิบายภาพที่นี่

ผู้เขียนคำถามจำเป็นต้องชี้แจงว่าความหมายของรายการค่า "ความน่าจะเป็น" คืออะไร "ความน่าจะเป็น" เป็นเพียงชื่อของตัวแปรการตอบสนอง (แล้วทำไมจึงมี x-label พร้อมสำหรับฮิสโตแกรมจึงไม่สมเหตุสมผล ) หรือเป็นค่ารายการที่ความน่าจะเป็นที่คำนวณได้จากข้อมูล (ความจริงที่ว่าพวกเขาไม่รวมกันถึง 1 ก็ไม่มีเหตุผล)


4

นี่เป็นวิธีการที่ครอบคลุมมาก แต่ถ้าคุณต้องการสร้างฮิสโตแกรมที่คุณรู้ค่า bin อยู่แล้ว แต่ไม่มีข้อมูลต้นทางคุณสามารถใช้np.random.randintฟังก์ชันเพื่อสร้างจำนวนค่าที่ถูกต้องภายในช่วงของแต่ละค่า bin สำหรับฟังก์ชัน hist ในการสร้างกราฟตัวอย่างเช่น:

import numpy as np
import matplotlib.pyplot as plt

data = [np.random.randint(0, 9, *desired y value*), np.random.randint(10, 19, *desired y value*), etc..]
plt.hist(data, histtype='stepfilled', bins=[0, 10, etc..])

สำหรับป้ายกำกับคุณสามารถจัดแนวเครื่องหมาย x กับถังขยะเพื่อให้ได้สิ่งนี้:

#The following will align labels to the center of each bar with bin intervals of 10
plt.xticks([5, 15, etc.. ], ['Label 1', 'Label 2', etc.. ])
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.