Bagaimana cara memplot histogram menggunakan Matplotlib dengan Python dengan daftar data?

103

Saya mencoba memplot histogram menggunakan matplotlib.hist()fungsi tersebut tetapi saya tidak yakin bagaimana melakukannya.

Saya punya daftar

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]

dan daftar nama (string).

Bagaimana cara menjadikan probabilitas sebagai nilai y saya untuk setiap batang dan nama sebagai nilai x?

DataVizGuys
sumber

Jawaban:

176

Jika Anda menginginkan histogram, Anda tidak perlu melampirkan 'nama' apa pun ke nilai x, karena pada sumbu x Anda akan memiliki tempat data:

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');

masukkan deskripsi gambar di sini

Anda dapat membuat histogram Anda sedikit lebih menarik dengan PDFgaris, judul, dan legenda:

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");

masukkan deskripsi gambar di sini

Namun, jika Anda memiliki jumlah titik data yang terbatas, seperti di OP, plot batang akan lebih masuk akal untuk mewakili data Anda (maka Anda dapat melampirkan label ke sumbu x):

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

masukkan deskripsi gambar di sini

Sergey Bushmanov
sumber
4
Ingat, tidak ada titik koma di akhir baris di python!
Toad22222
12
@ Toad22222 Ini adalah kutipan dari sel notebook Ipython. Cobalah untuk menjalankannya tanpa titik koma dan lihat perbedaannya. Semua potongan kode yang saya posting di SO berjalan dengan sempurna di komputer saya.
Sergey Bushmanov
3
Jika Anda bertanya-tanya tentang titik koma yang digunakan oleh Sergey, lihat di sini dan # 16 di sini untuk mengetahui cara titik koma digunakan dalam sel notebook Jupyter (sebelumnya notebook IPython) saat membuat plot untuk menyembunyikan teks tentang objek plot.
Wayne
20

Jika Anda belum menginstal matplotlib, coba saja perintahnya.

> pip install matplotlib

Impor perpustakaan

import matplotlib.pyplot as plot

Data histogram:

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

Tampilkan histogram

plot.show()

Dan hasilnya seperti:

masukkan deskripsi gambar di sini

Niraj
sumber
2
Garis plot.axis ([50, 110, 0, 0.06]) 'tidak berguna untuk contoh ini. Selain itu, karena sulit mengkodekan area plot untuk ditampilkan, jika data Anda tidak sepenuhnya pas di dalamnya, Anda mungkin bingung mengapa tidak ditampilkan dengan benar.
typhon04
10

Padahal pertanyaannya tampaknya menuntut perencanaan menggunakan histogram matplotlib.hist() fungsi, itu bisa dibilang tidak dilakukan menggunakan hal yang sama karena bagian terakhir dari pertanyaan menuntut untuk menggunakan probabilitas yang diberikan sebagai nilai-y dari bar dan nama yang diberikan (string) sebagai nilai x.

Saya mengasumsikan daftar contoh nama yang sesuai dengan probabilitas yang diberikan untuk menggambar plot. Di sini, plot batang sederhana berfungsi untuk masalah yang diberikan. Kode berikut dapat digunakan:

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')
Shayan Shafiq
sumber
5

Ini adalah pertanyaan lama tetapi tidak ada jawaban sebelumnya yang membahas masalah yang sebenarnya, yaitu fakta bahwa masalahnya ada pada pertanyaan itu sendiri.

Pertama, jika probabilitas sudah dihitung, yaitu data agregat histogram tersedia dengan cara yang dinormalisasi maka probabilitas harus berjumlah 1. Mereka jelas tidak dan itu berarti ada yang salah di sini, baik dengan terminologi atau dengan datanya atau dalam cara pertanyaan itu diajukan.

Kedua, fakta bahwa label disediakan (dan bukan interval) biasanya berarti bahwa probabilitasnya adalah variabel respons kategoris - dan penggunaan plot batang untuk memplot histogram adalah yang terbaik (atau beberapa peretasan metode hist pyplot), Jawaban Shayan Shafiq memberikan kodenya.

Namun, lihat masalah 1, probabilitas tersebut tidak benar dan menggunakan diagram batang dalam hal ini sebagai "histogram" akan salah karena tidak menceritakan kisah distribusi univariat, untuk beberapa alasan (mungkin kelasnya tumpang tindih dan pengamatan dihitung berganda kali?) dan plot seperti itu tidak boleh disebut histogram dalam kasus ini.

Histogram adalah representasi grafis dari distribusi variabel univariat (lihat https://www.itl.nist.gov/div898/handbook/eda/section3/histogra.htm , https://en.wikipedia.org/wiki /Histogram) dan dibuat dengan menggambar batang dengan ukuran yang mewakili jumlah atau frekuensi pengamatan di kelas tertentu dari variabel yang diminati. Jika variabel diukur pada skala kontinu, kelas-kelas itu adalah bin (interval). Bagian penting dari prosedur pembuatan histogram adalah membuat pilihan tentang cara mengelompokkan (atau mempertahankan tanpa pengelompokan) kategori respons untuk variabel kategori, atau cara membagi domain nilai yang mungkin menjadi interval (tempat meletakkan batas bin) untuk kontinu. jenis variabel. Semua pengamatan harus diwakili, dan masing-masing hanya satu kali dalam plot. Itu berarti bahwa jumlah ukuran batang harus sama dengan jumlah total pengamatan (atau luasnya dalam kasus lebar variabel, yang merupakan pendekatan yang kurang umum). Atau, jika histogram dinormalisasi maka semua probabilitas harus berjumlah 1.

Jika datanya sendiri berupa daftar "probabilitas" sebagai respons, yaitu pengamatan adalah nilai probabilitas (dari sesuatu) untuk setiap objek studi maka jawaban terbaik adalah plt.hist(probability)dengan opsi binning mungkin, dan penggunaan x-label yang sudah tersedia adalah mencurigakan.

Kemudian plot batang tidak boleh digunakan sebagai histogram melainkan sederhana

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

dengan hasil

masukkan deskripsi gambar di sini

matplotlib dalam kasus seperti itu datang secara default dengan nilai histogram berikut

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

hasilnya adalah tuple array, array pertama berisi jumlah observasi, yaitu apa yang akan ditampilkan terhadap sumbu y dari plot (jumlah tersebut berjumlah 13, jumlah total observasi) dan array kedua adalah batas interval untuk x -sumbu.

Seseorang dapat memeriksa apakah mereka memiliki jarak yang sama,

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

masukkan deskripsi gambar di sini

Atau, misalnya untuk 3 bins (penilaian saya memanggil 13 observasi) seseorang akan mendapatkan histogram ini

plt.hist(probability, bins=3)

masukkan deskripsi gambar di sini

dengan data plot "di balik jeruji"

masukkan deskripsi gambar di sini

Penulis pertanyaan perlu mengklarifikasi apa arti dari daftar nilai "probabilitas" - apakah "probabilitas" hanyalah nama variabel respons (lalu mengapa ada x-label yang siap untuk histogram, tidak masuk akal ), atau apakah daftar nilai probabilitas yang dihitung dari data (maka fakta bahwa mereka tidak menambahkan hingga 1 tidak masuk akal).

predmod
sumber
4

Ini adalah cara yang sangat bulat untuk melakukannya tetapi jika Anda ingin membuat histogram di mana Anda sudah mengetahui nilai bin tetapi tidak memiliki data sumber, Anda dapat menggunakan np.random.randintfungsi untuk menghasilkan jumlah nilai yang benar dalam rentang masing-masing. bin untuk fungsi hist ke grafik, misalnya:

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..])

Sedangkan untuk label, Anda dapat menyelaraskan x centang dengan tempat sampah untuk mendapatkan sesuatu seperti ini:

#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.. ])
Connor Wilmers
sumber