Matplotlib'deki kutu boyutu (Histogram)


149

Histogram yapmak için matplotlib kullanıyorum.

Kutuların boyutunu manuel olarak kutu sayısının aksine ayarlamanın bir yolu var mı?

Yanıtlar:


270

Aslında, oldukça kolay: çöp kutusu yerine çöp kutusu sınırları ile bir liste verebilirsiniz. Bunlar da eşit olmayan bir şekilde dağıtılabilir:

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

Sadece eşit olarak dağıtılmasını istiyorsanız, aralığı kullanabilirsiniz:

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

Orijinal yanıta eklendi

Yukarıdaki satır datasadece tamsayılarla dolu için geçerlidir. Macrocosme belirttiği gibi , şamandıralar için şunları kullanabilirsiniz:

import numpy as np
plt.hist(data, bins=np.arange(min(data), max(data) + binwidth, binwidth))

20
şamandıralarla çalışmak için aralığı (...) np.arange (...) ile değiştirin.
macrocosme

6
burada binwidth nedir? u bu değeri daha önce ayarladınız mı?
UserYmY

1
Bu örnekte binwidth: tarafından bulunabilir inanıyorum (data.max() - data.min()) / number_of_bins_you_want. Bu + binwidthsadece 1daha kolay anlaşılır bir örnek yapmak için değiştirilebilir .
Jarad

2
Yukarıdaki kodlamaCat'ın mükemmel çözümüne ek olarak, şamandıra verileri için, çubuk grafik sınırlarını x-kenelerinde tutmak yerine histogram çubuklarının tamsayı x-keneleri etrafında ortalanmasını istiyorsanız, aşağıdaki ayarları deneyin: bins = np.arange (dmin - 0.5, dmax + 0.5 + binwidth, binwidth)
DaveW

3
seçeneği lw = 5, color = "white"veya benzeri çubuklar arasında beyaz boşluklar ekler
PatrickT

13

N bölmeleri için, bölme kenarları, ilk N'nin alt bölme kenarlarını ve +1, son bölmenin üst kenarını verdiği N + 1 değerleri listesiyle belirtilir.

Kod:

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)

Linspace'in N + 1 değerlerine veya N bölmelerine ayrılmış min_edge'den max_edge'ye dizi oluşturduğunu unutmayın


1
Her iki sınırın da dahil olduğu N + 1 (son) çöp kutusu hariç, bölmelerin alt sınırlarını ve üst sınırlarını hariç tuttuğunu unutmayın.
lukewitmer

4

Sanırım en kolay yol, sahip olduğunuz verilerin minimum ve maksimum değerlerini hesaplamak ve sonra hesaplamak olacaktır L = max - min. Daha sonra Listenen bölme genişliğine bölün (bin boyutuna göre ne demek istediğinizi varsayalım) ve bu değerin tavanını kutu sayısı olarak kullanın.


tam olarak aklımda olan şey bu, teşekkürler. Sadece daha basit bir yol olup olmadığını merak ediyordum ama bu teşekkür bulmak görünüyor!
Sam Creamer

Yuvarlak sayılar kullanarak bu yaklaşımla yuvarlak kutu boyutu alamıyorum. Bunu yaşayan var mı?
Brad Urani

3

İşlerin otomatik olarak gerçekleşmesini ve çöp kutularının "güzel" değerlere düşmesini seviyorum. Aşağıdaki oldukça iyi çalışıyor gibi görünüyor.

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

Sonuçta güzel çöp kutusu aralıklarında kutular bulunur.

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

hesaplanmış kutular histogram


Tam olarak aradığım şey! Bununla birlikte, bazı durumlarda n_bins kayan nokta hassasiyeti nedeniyle aşağı yuvarlanır. İçin Örn desired_bin_size=0.05, min_boundary=0.850, max_boundary=2.05hesaplanması n_binshaline int(23.999999999999993)hangi sonuçları 23 yerine 24 ve bu nedenle bir bin çok az. Tamsayı dönüşümünden önce bir yuvarlama benim için çalıştı:n_bins = int(round((max_boundary - min_boundary) / desired_bin_size, 0)) + 1
M. Schlenker

3

Numuneleri tek tip ve örneklere uygun kovalar yapmak için kullanıyorum:

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

resim açıklamasını buraya girin


1
İyi fikir. Nicelik listesini np.arange(0, 1.01, 0.5)veya ile değiştirebilirsiniz np.linspace(0, 1, 21). Kenar yok, ancak kutuların eşit alana sahip olduğunu anlıyorum, ancak X ekseninde farklı genişlik?
Tomasz Gandor

2

OP ile aynı sorunu yaşadım (sanırım!), Ancak Lastalda'nın belirlediği şekilde çalışmaya başlayamadım. Soruyu doğru yorumlayıp yorumlamadığımı bilmiyorum, ama başka bir çözüm buldum (muhtemelen bunu yapmanın gerçekten kötü bir yolu).

Bunu yapmanın yolu buydu:

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

Hangi bunu oluşturur:

matplotlib'de oluşturulan histogram grafiğini gösteren resim

Bu yüzden ilk parametre temelde bin'i 'başlatır' - özellikle bins parametresinde ayarladığım aralık arasında bir sayı oluşturuyorum.

Bunu göstermek için, birinci parametrede diziye ([1,11,21,31,41]) ve ikinci parametrede '[bidonlar' dizisine ([0,10,20,30,40,50]) bakın. :

  • 1 sayısı (ilk diziden) 0 ile 10 arasındadır ('bölmeler' dizisinde)
  • 11 sayısı (ilk diziden) 11 ile 20 arasındadır ('kutu' dizisinde)
  • 21 sayısı (ilk diziden) 21 ile 30 arasında ('bölmeler' dizisinde) vb.

Sonra her bölmenin boyutunu tanımlamak için 'ağırlıklar' parametresini kullanıyorum. Bu, ağırlıklar parametresi için kullanılan dizidir: [10,1,40,33,6].

Böylece 0 ila 10 bölmesine 10 değeri verilir, 11 ila 20 bölmesine 1 değeri verilir, 21 ila 30 bölmesine 40 değeri verilir.


3
Bence histogram fonksiyonunun nasıl çalıştığı hakkında temel bir yanlış anlama var. Ham veri bekler. Dolayısıyla, örneğinizde, veri diziniz 0 ile 10 arasında 10, 10 ile 20 arasında 1 değer vb. İçermelidir. Daha sonra fonksiyon özetleme ve çizimi yapar. Yukarıda yaptığınız bir çözümdür, çünkü toplamlara zaten sahipsiniz (daha sonra "ağırlıklar" seçeneğini kötüye kullanarak grafiğe eklersiniz). Umarım bu biraz karışıklığı giderir.
CodingCat

-1

Tamsayı x-değeri olan bir histogram için şunu kullandım:

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

0,5 ofseti, kutuları x ekseni değerleri üzerinde ortalar. plt.xticksÇağrı her tamsayı için bir kene ekler.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.