Как построить гистограмму в python
Перейти к содержимому

Как построить гистограмму в python

  • автор:

Как создать гистограмму из Pandas DataFrame

Как создать гистограмму из Pandas DataFrame

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

df.hist (column='col_name') 

В следующих примерах показано, как использовать этот синтаксис на практике.

Пример 1. Построение одной гистограммы

В следующем коде показано, как создать одну гистограмму для определенного столбца в кадре данных pandas:

import pandas as pd #create DataFrame df = pd.DataFrame() #view first five rows of DataFrame df.head () points assists rebounds 0 25 5 11 1 12 7 8 2 15 7 10 3 14 9 6 4 19 12 6 #create histogram for 'points' column df.hist (column='points') 

Мы также можем настроить гистограмму с определенными цветами, стилями, метками и количеством ячеек:

#create custom histogram for 'points' column df.hist (column='points', bins= 5 , grid= False , rwidth= .9 , color='purple') 

Pandas гистограмма

По оси X отображаются очки, набранные каждым игроком, а по оси Y — частота количества игроков, набравших такое количество очков.

Пример 2: построение нескольких гистограмм

В следующем коде показано, как построить несколько гистограмм из кадра данных pandas:

import pandas as pd #create DataFrame df = pd.DataFrame() #view first five rows df.head () team points 0 A 25 1 A 12 2 A 15 3 A 14 4 A 19 #create histogram for each team df.hist (column='points', by='team', bins= 3 , grid= False , rwidth= .9 , color='purple', sharex= True ) 

несколько гистограмм в pandas

Обратите внимание, что аргумент sharex указывает, что две гистограммы должны иметь одну и ту же ось X.

Это упрощает сравнение распределения значений между двумя гистограммами.

Дополнительные ресурсы

В следующих руководствах объясняется, как создавать другие распространенные графики в Python:

Рисуем гистограммы, столбчатые и круговые диаграммы

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

Гистограмма и столбчатые диаграммы

Иногда данные требуется сгруппировать по определенным диапазонам и подсчитать сколько значений попадает в тот или иной интервал. Для выполнения такой задачи хорошо подходят столбчатые диаграммы и довольно известный их вид – это гистограмма распределения случайной величины.

Давайте сгенерируем вектор из 500 случайных величин и выведем их в виде гистограммы, используя функцию hist():

import numpy as np import matplotlib.pyplot as plt fig = plt.figure(figsize=(6, 4)) ax = fig.add_subplot() y = np.random.normal(0, 2, 500) ax.hist(y) ax.grid() plt.show()

На выходе получим следующее изображение распределения нормальной СВ:

Фактически, мы здесь имеем набор столбиков, высота которых определяется числом СВ, попавших в тот или иной диапазон. Причем, по умолчанию функция hist() разбивает весь интервал на равных 10 диапазонов. Если требуется изменить это число, то мы можем его указать вторым параметром:

ax.hist(y, 50)

Прежний интервал теперь разбит на 50 диапазонов, столбиков стало больше и они выглядят тоньше.

Функции bar() и barh()

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

x = [f'H' for i in range(10)] y = np.random.randint(1, 5, len(x)) ax.bar(x, y)

Или, можно отобразить то же распределение нормальной СВ с помощью такой столбчатой диаграммы. Сначала сформируем сами величины и разобьем весь интервал на 10 равных диапазонов:

y = np.random.normal(0, 2, 500) x = np.linspace(np.min(y), np.max(y), 10)

Затем, подсчитаем, сколько величин попало в соответствующий диапазон и выведем список bars с помощью функции bar():

bars = [len(y[np.bitwise_and(y >= x[i], y  x[i+1])]) for i in range(len(x)-1)] ax.bar(range(len(x)-1), bars)

Как видите, у нас получилось изображение аналогичное гистограмме. Только пришлось предварительно подготовить данные, что не очень удобно. Поэтому, когда нужно вывести распределение величин по диапазонам, то проще использовать функцию hist().

Если нам нужно отображать столбики относительно оси ординат, то для этого существует функция barh(), которая работает аналогично функции bar():

ax.barh(range(len(x)-1), bars)

В итоге, график будет выглядеть, следующим образом:

Гистограммы

Отличный способ начать изучение одной переменной — с помощью гистограммы. Гистограмма делит переменную на ячейки, подсчитывает точки данных в каждой ячейке и отображает ячейки на оси x и значения на оси y. В нашем случае бинами будет интервал времени, представляющий задержку рейсов, а количеством будет количество рейсов, попадающих в этот интервал. Binwidth является наиболее важным параметром для гистограммы, и мы всегда должны опробовать несколько различных значений binwidth, чтобы выбрать лучшее для наших данных.

Чтобы создать базовую гистограмму в Python, мы можем использовать либо matplotlib, либо seaborn. Код ниже показывает вызовы функций в обеих библиотеках, которые создают эквивалентные цифры. Для вызовов сюжета мы указываем ширину бина по количеству бинов. Для этого графика я буду использовать ячейки длиной 5 минут, что означает, что количество ячеек будет представлять собой диапазон данных (от -60 до 120 минут), разделенный на ширину ячейки, 5 минут ( bins = int(180/5) ).

Для большинства основных гистограмм я бы использовал код matplotlib, потому что он проще, но мы будем использовать seaborn distplot Позже вы сможете создавать различные дистрибутивы, и вам будет полезно ознакомиться с различными опциями.

Как я придумал 5 минут для пропускной способности? Единственный способ определить оптимальную ширину бина — это попробовать несколько значений! Ниже приведен код для создания того же рисунка в matplotlib с диапазоном ширины бина. В конечном счете, нет правильного или неправильного ответа на полосу пропускания, но я выбрал 5 минут, потому что я думаю, что это лучше всего представляет распределение.

Выбор ширины бина существенно влияет на результирующий сюжет. Меньшая пропускная способность может сделать помехи загроможденными, но большая пропускная способность может скрыть нюансы в данных. Matplotlib автоматически выберет разумную пропускную способность для вас, но я хотел бы сам указать ее, когда опробую несколько значений. Нет правильного или неправильного ответа, поэтому попробуйте несколько вариантов и посмотрите, какой из них лучше всего подходит для ваших конкретных данных.

Когда гистограммы терпят неудачу

Гистограммы — отличный способ начать исследование одной переменной, взятой из одной категории. Однако, когда мы хотим сравнить распределения одной переменной по нескольким категориям, у гистограмм возникают проблемы с удобочитаемостью. Например, если мы хотим сравнить распределения задержек прилета между авиакомпаниями, подход, который не работает должным образом, заключается в создании гистограмм для каждой авиакомпании на одном и том же участке:

(Обратите внимание, что ось Y была нормализована для учета различного количества рейсов между авиакомпаниями. Для этого передайте аргумент norm_hist = True к sns.distplot вызов функции.)

Этот сюжет не очень полезен! Все перекрывающиеся бары делают практически невозможным сравнение авиалиний. Давайте посмотрим на несколько возможных решений этой общей проблемы.

Решение № 1: параллельные гистограммы

Вместо того, чтобы перекрывать гистограммы авиакомпании, мы можем разместить их рядом. Для этого мы создаем список задержек прилета для каждой авиакомпании, а затем передаем это в plt.hist вызов функции в виде списка списков. Мы должны указать разные цвета для каждой авиакомпании и ярлык, чтобы мы могли различать их. Код, включая создание списков для каждой авиакомпании, приведен ниже:

По умолчанию, если мы передадим список списков, matplotlib разместит столбцы рядом. Здесь я изменил ширину бина на 15 минут, потому что в противном случае сюжет слишком загроможден, но даже с этой модификацией это не эффективный показатель. Слишком много информации для обработки сразу, столбцы не совпадают с метками, и все еще сложно сравнивать распределение между авиакомпаниями. Когда мы строим сюжет, мы хотим, чтобы зрителю было как можно проще его понять, и эта цифра не соответствует этим критериям! Давайте посмотрим на второе потенциальное решение.

Решение № 2: Сложенные бары

Вместо того, чтобы строить столбцы для каждой авиакомпании бок о бок, мы можем сложить их, передав параметр stacked = True на вызов гистограммы:

# Stacked histogram with multiple airlines
plt.hist([x1, x2, x3, x4, x5], bins = int(180/15), stacked=True,
normed=True, color = colors, label=names)

Ну, это точно не лучше! Здесь каждая авиакомпания представлена ​​как единое целое для каждой корзины, но сравнить ее практически невозможно. Например, с задержкой от -15 до 0 минут, имеет ли United Air Lines или JetBlue Airlines больший размер полосы? Я не могу сказать, и зрители не смогут либо. Я вообще не сторонник стековых баров, потому что их может быть сложно интерпретировать (хотя есть варианты использования например, при визуализации пропорций). Оба решения, которые мы пытались использовать с помощью гистограмм, не увенчались успехом, и пришло время перейти к графику плотности.

Графики плотности

Во-первых, что такое график плотности? график плотности является сглаженной, непрерывной версией гистограммы, оцененной по данным. Наиболее распространенная форма оценки известна как оценка плотности ядра, В этом методе непрерывная кривая (ядро) рисуется в каждой отдельной точке данных, и все эти кривые затем складываются, чтобы сделать единую плавную оценку плотности. Ядро, наиболее часто используемое — это гауссово (которое создает гауссову кривую колокола в каждой точке данных). Если, как и я, вы находите это описание немного запутанным, взгляните на следующий сюжет:

Здесь каждая маленькая черная вертикальная линия на оси x представляет точку данных. Отдельные ядра (в данном примере гауссианы) показаны пунктирными красными линиями над каждой точкой. Сплошная синяя кривая создается путем суммирования отдельных гауссианов и образует график общей плотности.

Ось X — это значение переменной, как в гистограмме, но что именно представляет ось Y? Ось Y на графике плотности является функцией плотности вероятности для оценки плотности ядра. Тем не менее, мы должны быть осторожны, чтобы указать, что это вероятностьплотностьа не вероятность. Разница заключается в Плотность вероятности — это вероятность на единицу по оси X, Чтобы преобразовать фактическую вероятность, нам нужно найти область под кривой для определенного интервала по оси X. Несколько запутанно, потому что это плотность вероятности, а не вероятность, Ось Y может принимать значения больше единицы. Единственным требованием графика плотности является то, что общая площадь под кривой интегрируется в единицу. Я обычно склонен думать об оси Y на графике плотности как о значении только для относительных сравнений между различными категориями.

Земельные участки в Seaborn

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

# Density Plot and Histogram of all arrival delays
sns.distplot(flights['arr_delay'], hist=True, kde=True,
bins=int(180/5), color = 'darkblue',
hist_kws=,
kde_kws=)

Кривая показывает график плотности, который по сути является гладкой версией гистограммы. Ось Y соответствует плотности, и гистограмма по умолчанию нормализована, так что она имеет тот же масштаб Y, что и график плотности.

Аналогично ширине гистограммы, график плотности имеет параметр, называемый пропускная способность это меняет отдельные ядра и существенно влияет на конечный результат сюжета. Библиотека черчения выберет для нас разумное значение пропускной способности (по умолчанию используя оценку Скотта), и в отличие от бинарной ширины гистограммы, я обычно использую пропускную способность по умолчанию Тем не менее, мы можем посмотреть на использование разных полос пропускания, чтобы увидеть, есть ли лучший выбор. На графике «scott» является значением по умолчанию, которое выглядит как лучший вариант

Обратите внимание, что более широкая полоса пропускания приводит к большему сглаживанию распределения. Мы также видим, что, хотя мы ограничиваем наши данные до -60 до 120 минут, график плотности выходит за эти пределы. Это одна потенциальная проблема с графиком плотности: поскольку он рассчитывает распределение в каждой точке данных, он может генерировать данные, выходящие за пределы исходных данных. Это может означать, что на оси x мы получим невозможные значения, которые никогда не присутствовали в исходных данных! Как примечание, мы также можем изменить ядро, которое меняет распределение, отображаемое в каждой точке данных, и, следовательно, общее распределение. Однако для большинства приложений ядро ​​по умолчанию, гауссово и оценка пропускной способности по умолчанию работают очень хорошо.

Решение № 3 График плотности

Теперь, когда мы понимаем, как строится график плотности и что он представляет, давайте посмотрим, как он может решить нашу проблему визуализации задержек прибытия нескольких авиакомпаний. Чтобы показать распределения на одном и том же участке, мы можем перебирать авиакомпании, каждый раз звоня distplot с оценкой плотности ядра, установленной на True, и гистограммой, установленной на False. Код для построения графика плотности с несколькими авиакомпаниями ниже:

Наконец-то мы пришли к эффективному решению! С графиком плотности, мы можем легко сделать сравнение между авиакомпаниями, потому что график менее загроможден. Теперь, когда у нас наконец есть сюжет, который мы хотим, мы приходим к выводу, что у всех этих авиакомпаний есть почти идентичные распределения задержек прилета! Однако в наборе данных есть другие авиакомпании, и мы можем нанести на график одну из них, которая будет немного отличаться, чтобы проиллюстрировать еще один необязательный параметр для графиков плотности, заштриховывая график.

Графики затененной плотности

Заполнение графика плотности может помочь нам различать перекрывающиеся распределения. Хотя это не всегда хороший подход, он может помочь подчеркнуть разницу между дистрибутивами. Чтобы затенить графики плотности, проходим в shade = True к kde_kws аргумент в distplot вызов.

sns.distplot(subset['arr_delay'], hist = False, kde = True, 
kde_kws = ,
label = airline)

Вопрос о том, стоит ли затенять сюжет, как и другие варианты прорисовки, зависит от проблемы! Для этого графика, я думаю, это имеет смысл, потому что затенение помогает нам различать графики в областях, где они перекрываются. Теперь у нас наконец есть некоторая полезная информация: рейсы авиакомпании Alaska Airlines выполняются раньше, чем United Airlines. В следующий раз, когда у вас есть возможность, вы знаете, какую авиакомпанию выбрать!

Коврики

Если вы хотите показать каждое значение в распределении, а не только сглаженную плотность, вы можете добавить график коврика. Это показывает каждую отдельную точку данных на оси X, что позволяет нам визуализировать все фактические значения. Преимущество использования Seaborn’s distplot является то, что мы можем добавить сюжет коврика с помощью одного вызова параметра rug = True (с некоторым форматированием также).

Со многими точками данных график коврика может быть переполнен, но для некоторых наборов данных может быть полезно просмотреть каждую точку данных. График коврика также позволяет нам увидеть, как график плотности «создает» данные там, где их нет, потому что он выполняет распределение ядра в каждой точке данных. Эти распределения могут утекать во всем диапазоне исходных данных и создавать впечатление, что задержки в авиакомпании Alaska Airlines короче и длиннее, чем фактически зафиксированные. Мы должны быть осторожны с этим артефактом графиков плотности и указать его зрителям!

Выводы

Надеемся, что этот пост предоставил вам ряд возможностей для визуализации одной переменной из одной или нескольких категорий. Есть еще более одномерные (с одной переменной) графики, которые мы можем сделать, такие как графики эмпирической совокупной плотности и квантиль-квантиль, но пока мы оставим это на гистограммах и графиках плотности (и на графиках ковров тоже!). Не беспокойтесь, если варианты кажутся ошеломляющими: с практикой сделать правильный выбор станет легче, и вы всегда можете обратиться за помощью в случае необходимости. Более того, зачастую не существует оптимального выбора, и «правильное» решение сводится к предпочтениям и целям визуализации. Хорошая вещь, независимо от того, какой сюжет вы хотите сделать, в Python найдется способ сделать это! Визуализации являются эффективным средством передачи результатов, и знание всех доступных параметров позволяет нам выбрать правильную фигуру для наших данных.

Я приветствую отзывы и конструктивную критику @koehrsen_will,

Построение гистограммы в python из экселя

Построена таблица в экселе. Нужно сделать гистограмму (столбцы) с последним и первым столбцом. Получилось сделать только линейный график. Знаю, что есть plt.bar(), однако при его применении выходит ошибка.

import pandas as pd import matplotlib.pyplot as plt data = pd.read_excel(r'C:\Users\User\Desktop\sr5.1.xlsx') df = pd.DataFrame(data, columns=['Unnamed: 4', 'Unnamed: 1']) x = df[2:9] x.plot(x='Unnamed: 1', y='Unnamed: 4') plt.grid('True') plt.show() 

введите сюда описание изображения введите сюда описание изображения Возможно, я не правильно использую plt.bar(), но:

x = df[2:9] plt.bar(x='Unnamed: 1', y='Unnamed: 4', alpha=0.5, height=0.8, width=0.4) plt.grid('True') plt.show() 

raise munits.ConversionError(‘Failed to convert value(s) to axis ‘ matplotlib.units.ConversionError: Failed to convert value(s) to axis units: ‘Unnamed: 4’

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *