Histogram Matplotlib

107

Więc mam mały problem. Mam zestaw danych w scipy, który jest już w formacie histogramu, więc mam środek pojemników i liczbę zdarzeń na pojemnik. Jak mogę teraz wykreślić jako histogram. Po prostu próbowałem

bins, n=hist()

ale to się nie podobało. Jakieś zalecenia?

madtowneast
źródło

Odpowiedzi:

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

wprowadź opis obrazu tutaj

Interfejs zorientowany obiektowo jest również prosty:

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

Jeśli używasz niestandardowych (niestałych) pojemników, możesz przekazać obliczenie szerokości za pomocą np.diff, przekazać szerokości ax.bari użyć ax.set_xticksdo oznaczenia krawędzi pojemnika:

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

wprowadź opis obrazu tutaj

unutbu
źródło
Czy istnieje sposób na przekazanie krawędzi bin do osi X wykresu słupkowego?
CMCDragonkai
@CMCDragonkai: plt.barjest widthparametrem może przyjmować szereg-podobnego obiektu (zamiast skalara). Więc możesz użyć width = np.diff(bins)zamiast width = 0.7 * (bins[1] - bins[0]).
unutbu
Ale samo widthustawienie ustawia tylko szerokość paska, prawda? Mówię o etykietach na osi X (to znaczy chcę zobaczyć rzeczywiste krawędzie pojemników będące etykietami na osi X). Powinno być podobne do tego, jak plt.histdziała.
CMCDragonkai,
2
@CMCDragonkai: Możesz użyć ax.set_xticksdo ustawienia xlabels. Dodałem powyżej przykład, aby pokazać, o co mi chodzi.
unutbu
22

Jeśli nie chcesz słupków, możesz to wykreślić w ten sposób:

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
źródło
6
Możesz także użyć ax.step.
tacaswell
12

Wiem, że to nie odpowiada na Twoje pytanie, ale zawsze kończę na tej stronie, kiedy szukam rozwiązania matplotlib do histogramów, ponieważ prosty histogram_demozostał usunięty ze strony galerii przykładów matplotlib.

Oto rozwiązanie, które nie wymaga numpyimportu. Importuję numpy tylko w celu wygenerowania danych xdo wykreślenia. Opiera się na funkcji histzamiast funkcji, barjak w odpowiedzi @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')

wprowadź opis obrazu tutaj

Sprawdź także galerię matplotlib i przykłady matplotlib .

tommy.carstensen
źródło
„Oto rozwiązanie, które nie wymaga numpy” - pierwsza linia kodu importuje numpy :)
Martin R.
2
@Martin R. To tylko do wygenerowania danych do wykreślenia. Zobacz linie 4-6. Nie ma sensu numpy.
tommy.carstensen
6

Jeśli chcesz skorzystać z pandas:

pandas.DataFrame({'x':hist[1][1:],'y':hist[0]}).plot(x='x',kind='bar')
Michael Malak
źródło
27
Jeśli masz zamiar zasugerować użycie pandas, prawdopodobnie powinieneś dołączyć link do ich witryny i bardziej szczegółowy przykład wyjaśniający, co się dzieje.
tacaswell
0

Myślę, że to może być przydatne dla kogoś.

Funkcja histogramu Numpy'ego, ku mojej irytacji (chociaż doceniam, że jest ku temu dobry powód), zwraca raczej krawędzie każdego pojemnika, a nie wartość kosza. Chociaż ma to sens w przypadku liczb zmiennoprzecinkowych, które mogą znajdować się w przedziale (tj. Wartość środkowa nie jest bardzo znacząca), nie jest to pożądane wyjście w przypadku wartości dyskretnych lub liczb całkowitych (0, 1, 2 itd.) . W szczególności długość koszy zwracanych z np. Histogramu nie jest równa długości zliczeń / gęstości.

Aby to obejść, użyłem np.digitize do kwantyzacji danych wejściowych i zwrócenia dyskretnej liczby pojemników wraz z ułamkiem zliczeń dla każdego pojemnika. Możesz łatwo edytować, aby uzyskać całkowitą liczbę zliczeń.

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

Odniesienia:

[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
źródło