Как построить график плотности python

Гистограммы

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

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

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

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

Читайте также:  Javascript сортировка массива объектов

Выбор ширины бина существенно влияет на результирующий сюжет. Меньшая пропускная способность может сделать помехи загроможденными, но большая пропускная способность может скрыть нюансы в данных. 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,

Источник

Оцените статью