Гістограма Матплотліб


107

Тож у мене є невелика проблема. У мене є набір даних у scipy, який вже є у форматі гістограми, тому у мене є центр бункерів та кількість подій на бін. Як я зараз можу побудувати графік, як гістограма. Я намагався просто робити

bins, n=hist()

але це не сподобалось. Будь-які рекомендації?

Відповіді:


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

введіть тут опис зображення

Об'єктно-орієнтований інтерфейс також простий:

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

Якщо ви використовуєте власні (непостійні) бункери, ви можете передавати обчислення ширини за допомогою np.diff, передавати ширини ax.barта використовувати ax.set_xticksдля позначення країв відрізка:

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

введіть тут опис зображення


Чи є спосіб передати бічні ребра до осі x гістограми?
CMCDragonkai

Параметр @CMCDragonkai: plt.bar' widthможе приймати об'єкт, схожий на масив (замість скалярного). Таким чином, ви можете використовувати width = np.diff(bins)замість цього width = 0.7 * (bins[1] - bins[0]).
unutbu

Але сама widthнастройка встановлює лише ширину смуги? Я говорю про мітки осі x (тобто я хочу бачити, щоб фактичні краї біка були мітками на осі x). Це має бути схожим на те, як plt.histпрацює.
CMCDragonkai

2
@CMCDragonkai: Ви можете використовувати ax.set_xticksдля встановлення xlabels. Я додав приклад вище, щоб показати, що я маю на увазі.
unutbu

22

Якщо ви не хочете, бари можна скласти так:

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

гістограма


6
Ви також можете використовувати ax.step.
tacaswell

12

Я знаю, що це не відповідає на ваше запитання, але я завжди опиняюсь на цій сторінці, коли шукаю рішення matplotlib на гістограмах, оскільки простий histogram_demoбув видалений зі сторінки прикладу matplotlib.

Ось рішення, яке не потрібно numpyімпортувати. Я імпортую лише numpy для створення даних, xякі підлягають графіку. Він покладається на функцію histзамість функції, barяк у відповіді @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')

введіть тут опис зображення

Також перегляньте галерею matplotlib та приклади matplotlib .


"Ось рішення, яке не вимагає numpy" - перший рядок коду імпортує numpy :)
Мартін Р.

2
@Martin R. Це лише для отримання даних, які потрібно побудувати. Дивіться рядки 4-6. Немає використання нуме.
tommy.carstensen

6

Якщо ви готові використовувати pandas:

pandas.DataFrame({'x':hist[1][1:],'y':hist[0]}).plot(x='x',kind='bar')

27
Якщо ви збираєтесь запропонувати використовувати, pandasвам, ймовірно, слід включити посилання на їхній сайт і більше на прикладі, який пояснює, що відбувається.
tacaswell

0

Я думаю, що це може бути корисним для когось.

Функція гістограми Numpy, на мій роздратування (хоча, я вважаю, що є вагома причина для цього), повертає назад краї кожного контейнера, а не значення бункера. Хоча це має сенс для чисел з плаваючою комою, які можуть лежати в інтервалі (тобто центральне значення не надто значуще), це не бажаний вихід при роботі з дискретними значеннями або цілими числами (0, 1, 2 і т.д.) . Зокрема, довжина бункерів, повернених з np.гістограми, не дорівнює довжині підрахунків / щільності.

Щоб обійти це, я використав np.digitize для квантування вхідних даних і повернення дискретного числа бункерів, а також частки підрахунків для кожного контейнера. Ви можете легко редагувати, щоб отримати цілу кількість підрахунків.

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

Відгуки:

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

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.