Ukuran nampan di Matplotlib (Histogram)

149

Saya menggunakan matplotlib untuk membuat histogram.

Apakah ada cara untuk secara manual mengatur ukuran nampan yang bertentangan dengan jumlah nampan?

Sam Creamer
sumber

Jawaban:

270

Sebenarnya, ini cukup mudah: alih-alih jumlah sampah Anda dapat memberikan daftar dengan batas bin. Mereka juga dapat didistribusikan secara tidak merata:

plt.hist(data, bins=[0, 10, 20, 30, 40, 50, 100])

Jika Anda hanya ingin mereka terdistribusi secara merata, Anda cukup menggunakan rentang:

plt.hist(data, bins=range(min(data), max(data) + binwidth, binwidth))

Ditambahkan ke jawaban asli

Baris di atas hanya berfungsi untuk datadiisi dengan bilangan bulat. Seperti yang ditunjukkan oleh macrocosme , untuk mengapung Anda dapat menggunakan:

import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))
CodingCat
sumber
20
ganti range (...) dengan np.arange (...) untuk membuatnya bekerja dengan float.
macrocosme
6
apa binwidth di sini? sudahkah Anda menetapkan nilai itu sebelumnya?
UserYmY
1
Saya percaya binwidth dalam contoh ini dapat ditemukan oleh: (data.max() - data.min()) / number_of_bins_you_want. The + binwidthdapat diubah hanya 1untuk membuat ini contoh yang lebih mudah dipahami.
Jarad
2
Lebih jauh ke solusi CodingCat yang sangat baik di atas, untuk data float, jika Anda ingin bilah histogram berpusat di sekitar bilangan x ticks alih-alih memiliki batas bilah di x-tick, coba tweak berikut: bins = np.arange (dmin - 0,5, dmax + 0,5 + binwidth, binwidth)
DaveW
3
pilihan lw = 5, color = "white"atau menyisipkan celah putih antara bar
PatrickT
13

Untuk N nampan, tepi nampan ditentukan oleh daftar nilai N +1 di mana N pertama memberikan tepi nampan yang lebih rendah dan +1 memberi tepi atas dari nampan terakhir.

Kode:

from numpy import np; from pylab import *

bin_size = 0.1; min_edge = 0; max_edge = 2.5
N = (max_edge-min_edge)/bin_size; Nplus1 = N + 1
bin_list = np.linspace(min_edge, max_edge, Nplus1)

Perhatikan bahwa linspace menghasilkan array dari min_edge ke max_edge yang dipecah menjadi nilai N +1 atau N bin

Alef
sumber
1
Perhatikan bahwa nampan termasuk batas bawah dan eksklusif batas atas mereka, dengan pengecualian dari N + 1 (terakhir) nampan yang termasuk kedua batas.
suam
4

Saya kira cara mudahnya adalah dengan menghitung minimum dan maksimum data yang Anda miliki, lalu hitung L = max - min. Kemudian Anda membagi Ldengan lebar bin yang diinginkan (saya berasumsi ini adalah apa yang Anda maksud dengan ukuran bin) dan menggunakan plafon dari nilai ini sebagai jumlah bin.

Il-Bhima
sumber
itulah yang ada dalam pikiran saya, terima kasih. Tadinya hanya bertanya-tanya apakah ada cara yang lebih sederhana tetapi ini sepertinya menemukan terima kasih!
Sam Creamer
Menggunakan angka bulat saya tidak mendapatkan ukuran tempat sampah dengan pendekatan ini. Adakah yang mengalaminya?
Brad Urani 13
3

Saya suka hal-hal terjadi secara otomatis dan untuk sampah jatuh pada nilai-nilai "baik". Berikut ini tampaknya bekerja dengan cukup baik.

import numpy as np
import numpy.random as random
import matplotlib.pyplot as plt
def compute_histogram_bins(data, desired_bin_size):
    min_val = np.min(data)
    max_val = np.max(data)
    min_boundary = -1.0 * (min_val % desired_bin_size - min_val)
    max_boundary = max_val - max_val % desired_bin_size + desired_bin_size
    n_bins = int((max_boundary - min_boundary) / desired_bin_size) + 1
    bins = np.linspace(min_boundary, max_boundary, n_bins)
    return bins

if __name__ == '__main__':
    data = np.random.random_sample(100) * 123.34 - 67.23
    bins = compute_histogram_bins(data, 10.0)
    print(bins)
    plt.hist(data, bins=bins)
    plt.xlabel('Value')
    plt.ylabel('Counts')
    plt.title('Compute Bins Example')
    plt.grid(True)
    plt.show()

Hasilnya memiliki nampan pada interval ukuran bin yang bagus.

[-70. -60. -50. -40. -30. -20. -10.   0.  10.  20.  30.  40.  50.  60.]

histogram tempat sampah dihitung

pay_it_forward
sumber
Persis apa yang saya cari! Namun, dalam beberapa kasus n_bins dibulatkan ke bawah karena presisi floating point. Misalnya untuk desired_bin_size=0.05, min_boundary=0.850, max_boundary=2.05perhitungan n_binsmenjadi int(23.999999999999993)yang menghasilkan 23 bukan 24 dan oleh karena itu salah satu bin terlalu sedikit. Pembulatan sebelum konversi bilangan bulat bekerja untuk saya:n_bins = int(round((max_boundary - min_boundary) / desired_bin_size, 0)) + 1
M. Schlenker
3

Saya menggunakan kuantil untuk membuat tempat sampah seragam dan dipasang ke sampel:

bins=df['Generosity'].quantile([0,.05,0.1,0.15,0.20,0.25,0.3,0.35,0.40,0.45,0.5,0.55,0.6,0.65,0.70,0.75,0.80,0.85,0.90,0.95,1]).to_list()

plt.hist(df['Generosity'], bins=bins, normed=True, alpha=0.5, histtype='stepfilled', color='steelblue', edgecolor='none')

masukkan deskripsi gambar di sini

Wojciech Moszczyński
sumber
1
Ide yang hebat. Anda bisa mengganti daftar kuantil dengan np.arange(0, 1.01, 0.5)atau np.linspace(0, 1, 21). Tidak ada tepi, tapi saya mengerti kotak memiliki luas yang sama, tetapi lebarnya berbeda pada sumbu X?
Tomasz Gandor
2

Saya memiliki masalah yang sama dengan OP (saya pikir!), Tetapi saya tidak bisa membuatnya bekerja seperti yang ditentukan Lastalda. Saya tidak tahu apakah saya telah menafsirkan pertanyaan dengan benar, tetapi saya telah menemukan solusi lain (mungkin ini cara yang sangat buruk untuk melakukannya).

Ini adalah cara saya melakukannya:

plt.hist([1,11,21,31,41], bins=[0,10,20,30,40,50], weights=[10,1,40,33,6]);

Yang menciptakan ini:

gambar yang menunjukkan grafik histogram dibuat di matplotlib

Jadi, parameter pertama pada dasarnya 'menginisialisasi' nampan - saya secara khusus membuat angka di antara rentang yang saya atur di parameter bins.

Untuk mendemonstrasikan ini, lihat array di parameter pertama ([1,11,21,31,41]) dan array 'sampah' di parameter kedua ([0,10,20,30,40,50]) :

  • Angka 1 (dari array pertama) jatuh antara 0 dan 10 (dalam array 'sampah')
  • Angka 11 (dari array pertama) jatuh antara 11 dan 20 (dalam array 'sampah')
  • Angka 21 (dari array pertama) jatuh antara 21 dan 30 (dalam array 'sampah'), dll.

Lalu saya menggunakan parameter 'bobot' untuk menentukan ukuran setiap bin. Ini adalah larik yang digunakan untuk parameter bobot: [10,1,40,33,6].

Jadi bin 0 hingga 10 diberi nilai 10, bin 11 hingga 20 diberi nilai 1, 21 hingga 30 bin diberi nilai 40, dll.

bluguy
sumber
3
Saya pikir Anda memiliki kesalahpahaman dasar tentang cara kerja fungsi histogram. Ia mengharapkan data mentah. Jadi, dalam contoh Anda, array data Anda harus berisi 10 nilai antara 0 hingga 10, 1 nilai antara 10 dan 20, dan seterusnya. Kemudian fungsi melakukan penjumlahan DAN gambar. Apa yang Anda lakukan di atas adalah solusi karena Anda sudah memiliki jumlah (yang kemudian Anda masukkan ke dalam grafik dengan menyalahgunakan opsi "bobot"). Semoga ini bisa menghilangkan beberapa kebingungan.
CodingCat
-1

Untuk histogram dengan integer x-values ​​akhirnya saya gunakan

plt.hist(data, np.arange(min(data)-0.5, max(data)+0.5))
plt.xticks(range(min(data), max(data)))

Offset 0,5 terpusat pada nampan pada nilai sumbu x. The plt.xtickspanggilan menambahkan tanda centang untuk setiap bilangan bulat.

Adversus
sumber