2013-10-06 9 views
22

Chciałbym użyć Matplotlib do wykreślenia histogramu dla danych, które zostały wcześniej zliczone. Na przykład, że mam dane suroweWykreślanie histogramu z wcześniej zliczonych danych w Matplotlib

data = [1, 2, 2, 3, 4, 5, 5, 5, 5, 6, 10] 

Biorąc pod uwagę te dane, można użyć

pylab.hist(data, bins=[...]) 

wykreślić histogram.

W moim przypadku, dane zostały wstępnie liczone i jest reprezentowany jako słownik:

counted_data = {1: 1, 2: 2, 3: 1, 4: 1, 5: 4, 6: 1, 10: 1} 

Idealnie, chciałbym przekazać tej pre-liczony dane do funkcji histogramu, który pozwala mi kontrolę szerokość kosza, zakres wydruku, itp., tak jakbym przekazał mu surowe dane. Jako obejście, jestem rozszerza moje liczniki do surowych danych:

data = list(chain.from_iterable(repeat(value, count) 
      for (value, count) in counted_data.iteritems())) 

To jest nieefektywne gdy counted_data zawiera liczbę milionów punktów danych.

Czy jest łatwiejszy sposób użycia Matplotlib do tworzenia histogramu z moich wcześniej zliczonych danych?

Alternatywnie, jeśli najłatwiej jest po prostu spakować dane, które zostały wstępnie zbuforowane, czy istnieje wygodna metoda polegająca na "zwijaniu" licznika pojedynczych elementów do liczby binów?

+1

Jak sidenote: poszerzyć swoje liczniki do surowych danych, można również użyć 'klasę Counter' i jego elementy() metoda: ' ze zbiorów importować Counter ' ' c = Counter (counted_data) ' ' data = lista (c.elements()) ' – fireboot

Odpowiedz

14

użyłem pyplot.hist „s weights opcję ważyć każdy klucz od jego wartości, produkujących histogram, który chciałem:

pylab.hist(counted_data.keys(), weights=counted_data.values(), bins=range(50))

ten pozwala mi polegać na hist, aby ponownie zebrać moje dane.

+0

, a twój sposób uzyskiwania danych ma większy sens niż mój. W porządku, jeśli przyjmiesz własną odpowiedź. – tacaswell

+0

To była wskazówka, której potrzebowałem. W moim przypadku mam listę zliczeń i zakresy bin: 'plt.hist (bin, bin = len (bin), weight = count)' było inwokacją, której potrzebowałem –

17

Można użyć argumentu weights słów kluczowych, aby np.histgram (co plt.hist połączenia pod spodem)

val, weight = zip(*[(k, v) for k,v in counted_data.items()]) 
plt.hist(val, weights=weight) 

Zakładając tylko mieć liczb całkowitych jako klucze, można również użyć bar bezpośrednio:

min_bin = np.min(counted_data.keys()) 
max_bin = np.max(counted_data.keys()) 

bins = np.arange(min_bin, max_bin + 1) 
vals = np.zeros(max_bin - min_bin + 1) 

for k,v in counted_data.items(): 
    vals[k - min_bin] = v 

plt.bar(bins, vals, ...) 

gdzie ... jest to argumenty, które chcesz przekazać bar(doc)

Jeśli chcesz ponownie bin dane zobaczyć Histogram with separate list denoting frequency

+0

Dzięki za wskaźnik do opcji' wagi '; Przeoczyłem to, ale to rozwiązuje mój problem idealnie (zobacz moją odpowiedź). –

+0

Nie udało mi się nawiązać takiego połączenia (zostałem oślepiony przez bezpośrednie użycie 'bar'). Edytowane w celu odzwierciedlenia Twojego komentarza. – tacaswell

0

Długość tablicy "bins" powinna być większa niż długość "counts". Oto sposób, aby w pełni zrekonstruować histogram:

import numpy as np 
import matplotlib.pyplot as plt 
bins = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9]).astype(float) 
counts = np.array([5, 3, 4, 5, 6, 1, 3, 7]).astype(float) 
centroids = (bins[1:] + bins[:-1])/2 
counts_, bins_, _ = plt.hist(centroids, bins=len(counts), 
          weights=counts, range=(min(bins), max(bins))) 
plt.show() 
assert np.allclose(bins_, bins) 
assert np.allclose(counts_, counts) 
Powiązane problemy