Как построить гистограмму с помощью Matplotlib в Python со списком данных?

104

Я пытаюсь построить гистограмму с помощью matplotlib.hist()функции, но не знаю, как это сделать.

У меня есть список

probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]

и список имен (строк).

Как сделать вероятность в качестве значения y для каждого столбца, а имена - в виде значений x?

DataVizGuys
источник

Ответы:

176

Если вам нужна гистограмма, вам не нужно прикреплять какие-либо `` имена '' к значениям x, так как на оси x у вас будут бункеры данных:

import matplotlib.pyplot as plt
import numpy as np
%matplotlib inline
np.random.seed(42)
x = np.random.normal(size=1000)
plt.hist(x, density=True, bins=30)  # `density=False` would make counts
plt.ylabel('Probability')
plt.xlabel('Data');

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

Вы можете сделать свою гистограмму более привлекательной, добавив PDFлинии, заголовки и легенды:

import scipy.stats as st
plt.hist(x, density=True, bins=30, label="Data")
mn, mx = plt.xlim()
plt.xlim(mn, mx)
kde_xs = np.linspace(mn, mx, 301)
kde = st.gaussian_kde(x)
plt.plot(kde_xs, kde.pdf(kde_xs), label="PDF")
plt.legend(loc="upper left")
plt.ylabel('Probability')
plt.xlabel('Data')
plt.title("Histogram");

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

Однако, если у вас ограниченное количество точек данных, как в OP, гистограмма будет иметь больше смысла для представления ваших данных (тогда вы можете прикрепить метки к оси x):

x = np.arange(3)
plt.bar(x, height=[1,2,3])
plt.xticks(x, ['a','b','c'])

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

Сергей Бушманов
источник
4
Помните, что в Python в конце строк не должно быть точек с запятой!
Toad22222
12
@ Toad22222 Это отрывок из ячейки ноутбука Ipython. Попробуйте выполнить его без точки с запятой и увидите разницу. Все фрагменты кода, которые я публикую на SO, отлично работают на моем компьютере.
Сергей Бушманов
3
Если вас интересует точка с запятой, которую использует Сергей, см. Здесь и # 16 здесь, чтобы узнать, как точка с запятой используется в ячейках записных книжек Jupyter (ранее записных книжек IPython) при построении графика для подавления текста об объекте графика.
Уэйн
20

Если вы еще не установили matplotlib, просто попробуйте команду.

> pip install matplotlib

Импорт библиотеки

import matplotlib.pyplot as plot

Данные гистограммы:

plot.hist(weightList,density=1, bins=20) 
plot.axis([50, 110, 0, 0.06]) 
#axis([xmin,xmax,ymin,ymax])
plot.xlabel('Weight')
plot.ylabel('Probability')

Показать гистограмму

plot.show()

И результат такой:

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

Нирадж
источник
2
Строка plot.axis ([50, 110, 0, 0.06]) 'в данном примере бесполезна. Кроме того, поскольку он жестко кодирует отображаемую область графика, если ваши данные не помещаются полностью внутри него, вы можете быть сбиты с толку, почему они отображаются неправильно.
typhon04
10

Хотя вопрос, по-видимому, требует построения гистограммы с использованием matplotlib.hist()функции, это, возможно, не может быть выполнено с использованием того же самого, что и последняя часть вопроса требует использования заданных вероятностей в качестве значений y столбцов и заданных имен (строк) в качестве x-значения.

Я предполагаю примерный список имен, соответствующих заданным вероятностям рисования сюжета. Простая диаграмма столбца служит цели здесь для данной задачи. Можно использовать следующий код:

import matplotlib.pyplot as plt
probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]
names = ['name1', 'name2', 'name3', 'name4', 'name5', 'name6', 'name7', 'name8', 'name9',
'name10', 'name11', 'name12', 'name13'] #sample names
plt.bar(names, probability)
plt.xticks(names)
plt.yticks(probability) #This may be included or excluded as per need
plt.xlabel('Names')
plt.ylabel('Probability')
Шаян Шафик
источник
5

Это старый вопрос, но ни один из предыдущих ответов не касался реальной проблемы, то есть того факта, что проблема связана с самим вопросом.

Во-первых, если вероятности уже были рассчитаны, т. Е. Агрегированные данные гистограммы доступны в нормализованном виде, тогда вероятности должны составлять в сумме 1. Очевидно, нет, и это означает, что здесь что-то не так, либо с терминологией, либо с данными. или в том, как задается вопрос.

Во-вторых, тот факт, что предоставляются метки (а не интервалы), обычно означает, что вероятности являются категориальной переменной отклика - и лучше всего использовать гистограмму для построения гистограммы (или некоторый взлом метода hist pyplot), Ответ Шаяна Шафика предоставляет код.

Однако см. Вопрос 1, эти вероятности неверны, и использование гистограммы в этом случае в качестве «гистограммы» было бы неправильным, потому что по какой-то причине она не рассказывает историю одномерного распределения (возможно, классы перекрываются, и наблюдения подсчитываются многократно. раз?) и такой график в данном случае не следует называть гистограммой.

Гистограмма по определению является графическим представлением распределения одномерной переменной (см. Https://www.itl.nist.gov/div898/handbook/eda/section3/histogra.htm , https://en.wikipedia.org/wiki / Гистограмма) и создается путем рисования полосок размеров, представляющих количество или частоту наблюдений в выбранных классах интересующей переменной. Если переменная измеряется в непрерывной шкале, эти классы являются ячейками (интервалами). Важной частью процедуры создания гистограммы является выбор того, как сгруппировать (или сохранить без группировки) категории ответов для категориальной переменной или как разбить область возможных значений на интервалы (где поставить границы бункера) для непрерывной тип переменная. Все наблюдения должны быть представлены, и каждое только один раз на графике. Это означает, что сумма размеров столбцов должна быть равна общему количеству наблюдений (или их площадям в случае переменной ширины, что является менее распространенным подходом). Или, если гистограмма нормализована, тогда все вероятности должны быть в сумме до 1.

Если сами данные представляют собой список «вероятностей» в качестве ответа, т. Е. Наблюдения представляют собой значения вероятности (чего-либо) для каждого объекта исследования, тогда лучшим ответом будет просто plt.hist(probability)вариант биннинга, а использование уже доступных x-меток - подозрительно.

Тогда столбиковый график не следует использовать как гистограмму, а просто

import matplotlib.pyplot as plt
probability = [0.3602150537634409, 0.42028985507246375, 
  0.373117033603708, 0.36813186813186816, 0.32517482517482516, 
  0.4175257731958763, 0.41025641025641024, 0.39408866995073893, 
  0.4143222506393862, 0.34, 0.391025641025641, 0.3130841121495327, 
  0.35398230088495575]
plt.hist(probability)
plt.show()

с результатами

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

matplotlib в таком случае прибывает по умолчанию со следующими значениями гистограммы

(array([1., 1., 1., 1., 1., 2., 0., 2., 0., 4.]),
 array([0.31308411, 0.32380469, 0.33452526, 0.34524584, 0.35596641,
        0.36668698, 0.37740756, 0.38812813, 0.39884871, 0.40956928,
        0.42028986]),
 <a list of 10 Patch objects>)

результатом является кортеж массивов, первый массив содержит счетчики наблюдений, то есть то, что будет показано относительно оси y графика (в сумме они дают 13, общее количество наблюдений), а второй массив - это границы интервала для x -ось.

Можно проверить, они равномерно расположены,

x = plt.hist(probability)[1]
for left, right in zip(x[:-1], x[1:]):
  print(left, right, right-left)

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

Или, например, для 3 ячеек (на мой взгляд, 13 наблюдений) можно получить эту гистограмму

plt.hist(probability, bins=3)

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

с сюжетными данными "за решеткой"

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

Автору вопроса необходимо уточнить, что означает список значений «вероятность» - это «вероятность» просто имя переменной ответа (тогда зачем там готовые х-метки для гистограммы, смысла нет ), или значения списка - вероятности, вычисленные на основе данных (тогда тот факт, что они не дают в сумме 1, не имеет смысла).

предмод
источник
4

Это очень обходной способ сделать это, но если вы хотите создать гистограмму, в которой вы уже знаете значения бункеров, но не имеете исходных данных, вы можете использовать np.random.randintфункцию для генерации правильного количества значений в диапазоне каждого bin для графической функции hist, например:

import numpy as np
import matplotlib.pyplot as plt

data = [np.random.randint(0, 9, *desired y value*), np.random.randint(10, 19, *desired y value*), etc..]
plt.hist(data, histtype='stepfilled', bins=[0, 10, etc..])

Что касается меток, вы можете выровнять x галочки с ячейками, чтобы получить что-то вроде этого:

#The following will align labels to the center of each bar with bin intervals of 10
plt.xticks([5, 15, etc.. ], ['Label 1', 'Label 2', etc.. ])
Коннор Уилмерс
источник