Histogram Matplotlib

107

Jadi saya punya sedikit masalah. Saya memiliki kumpulan data di scipy yang sudah dalam format histogram, jadi saya memiliki pusat nampan dan jumlah kejadian per bin. Bagaimana sekarang saya bisa memplot adalah sebagai histogram. Saya mencoba hanya melakukan

bins, n=hist()

tapi tidak seperti itu. Ada rekomendasi?

madtowneast
sumber

Jawaban:

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

masukkan deskripsi gambar di sini

Antarmuka berorientasi objek juga mudah:

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

Jika Anda menggunakan tempat sampah kustom (non-konstan), Anda dapat meneruskan menghitung lebar menggunakan np.diff, meneruskan lebar ke ax.bardan menggunakan ax.set_xticksuntuk memberi label tepi tempat sampah:

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

masukkan deskripsi gambar di sini

unutbu
sumber
Apakah ada cara untuk melewatkan tepi bin ke sumbu x pada grafik batang?
CMCDragonkai
@CMCDragonkai: plt.bar's widthparameter dapat menerima array-seperti objek (bukan skalar). Jadi, Anda bisa menggunakan width = np.diff(bins)bukan width = 0.7 * (bins[1] - bins[0]).
unutbu
Tetapi width pengaturan itu sendiri hanya mengatur lebar bilah, bukan? Saya berbicara tentang label sumbu x (yaitu saya ingin melihat tepi bin yang sebenarnya menjadi label pada sumbu x). Ini harus serupa dengan cara plt.histkerjanya.
CMCDragonkai
2
@CMCDragonkai: Anda dapat menggunakan ax.set_xticksuntuk mengatur xlabel. Saya telah menambahkan contoh di atas untuk menunjukkan apa yang saya maksud.
unutbu
22

Jika Anda tidak menginginkan bilah, Anda dapat memplotnya seperti ini:

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

histogram

Matthias123
sumber
6
Anda juga bisa menggunakan ax.step.
tacaswell
12

Saya tahu ini tidak menjawab pertanyaan Anda, tetapi saya selalu berakhir di halaman ini, ketika saya mencari solusi matplotlib untuk histogram, karena sederhana histogram_demo telah dihapus dari halaman galeri contoh matplotlib.

Inilah solusinya, yang tidak perlu numpydiimpor. Saya hanya mengimpor numpy untuk menghasilkan data yang xakan diplot. Ini bergantung pada fungsi histdaripada fungsi barseperti pada jawaban oleh @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')

masukkan deskripsi gambar di sini

Lihat juga galeri matplotlib dan contoh matplotlib .

tommy.carstensen
sumber
"Ini solusi, yang tidak memerlukan numpy" - baris pertama kode impor numpy :)
Martin R.
2
@Martin R. Itu hanya untuk menghasilkan data yang akan diplot. Lihat baris 4-6. Tidak ada gunanya numpy.
tommy.carstensen
6

Jika Anda ingin menggunakan pandas:

pandas.DataFrame({'x':hist[1][1:],'y':hist[0]}).plot(x='x',kind='bar')
Michael Malak
sumber
27
Jika Anda akan menyarankan penggunaan, pandasAnda mungkin harus menyertakan tautan ke situs mereka dan lebih banyak contoh yang menjelaskan apa yang sedang terjadi.
tacaswell
0

Saya pikir ini mungkin berguna untuk seseorang.

Fungsi histogram Numpy, yang membuat saya kesal (meskipun, saya menghargai ada alasan bagus untuk itu), mengembalikan tepi setiap tempat sampah, daripada nilai tempat sampah. Meskipun, ini masuk akal untuk bilangan floating-point, yang dapat berada dalam interval (yaitu nilai pusat tidak terlalu berarti), ini bukan keluaran yang diinginkan saat berhadapan dengan nilai diskrit atau bilangan bulat (0, 1, 2, dll) . Secara khusus, panjang nampan yang dikembalikan dari np. Histogram tidak sama dengan panjang hitungan / kepadatan.

Untuk menyiasati ini, saya menggunakan np.digitize untuk menghitung input, dan mengembalikan sejumlah tempat sampah, bersama dengan pecahan jumlah untuk setiap bin. Anda dapat dengan mudah mengedit untuk mendapatkan jumlah bilangan bulat dari hitungan.

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
####

Referensi:

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

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

sirgogo
sumber