Различные варианты визуализации данных с примерами кода.

Визуализация данных — это большая часть работы специалистов в области data science. На ранних стадиях развития проекта часто необходимо выполнять разведочный анализ данных (РАД, Exploratory data analysis (EDA)), чтобы выявить закономерности, которые обнаруживают данные. Визуализация данных помогает представить большие и сложные наборы данных в простом и наглядном виде. На этапе окончания проекта важно суметь отчитаться о его результатах так, чтобы даже непрофессионалам, не обладающим техническими знаниями, всё стало ясно и понятно.

https://t.me/machinelearning_interview – вопросы с собеседований DS.

Matplotlib — это популярная библиотека для визуализации данных, написанная на языке Python. Хоть пользоваться ей очень просто, настройка данных, параметров, графиков и отрисовки для каждого нового проекта — занятие нудное и утомительное. В этом посте мы разберем 6 способов визуализации данных и напишем быстрые и простые функции для их реализации с помощью питоновской библиотеки Matplotlib. А пока взгляните на прекрасный график, который поможет вам выбрать правильный тип визуализации данных!

Алгоритм выбора техники визуализации в зависимости от задачи

Диаграммы рассеяния (Scatter Plots)

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

 Различные варианты визуализации данных с примерами кода.
Диаграмма рассеяния с группировкой по цветам
 Различные варианты визуализации данных с примерами кода.
Диаграмма рассеяния с группировкой по цветам и по размерам для отображения -го параметра — размера страны

Теперь что касается кода. Сначала мы импортируем в Python библиотеку Matplotlib, а точнее её модуль pyplot, для краткости используя аббревиатуру «plt». Чтобы создать новый график, мы вызываем функцию plt.subplots(). Затем передаем данные оси x и оси y в функцию, а затем уже всё вместе передаем функции ax.scatter() для построения диаграммы рассеяния. Мы также можем установить размер точки, цвет точки и альфа-прозрачность. Можно даже использовать логарифмическую шкалу для оси y. Затем задаем заголовок и метки для осей. Это простая в использовании функция позволяет с нуля создать и отрисовать диаграмму рассеяния!

import matplotlib.pyplot as plt
import numpy as np

def scatterplot(x_data, y_data, x_label="", y_label="", title="", color = "r", yscale_log=False):

    # Create the plot object
    _, ax = plt.subplots()

    # Plot the data, set the size (s), color and transparency (alpha)
    # of the points
    ax.scatter(x_data, y_data, s = 10, color = color, alpha = 0.75)

    if yscale_log == True:
        ax.set_yscale('log')

    # Label the axes and provide a title
    ax.set_title(title)
    ax.set_xlabel(x_label)

Графики

Графики лучше всего использовать тогда, когда одна переменная сильно варьируется в зависимости от другой, другими словами, когда у них высокая ковариация. Давайте посмотрим на рисунок ниже, чтобы проиллюстрировать это. График наглядно показывает большой разброс процентного соотношения за указанный промежуток времени. Если бы эти же данные мы представили в виде диаграммы рассеяния, она была бы чрезвычайно загроможденной и сложной, что затрудняло бы понимание и визуальное отображение рассматриваемой зависимости. Графики, выполненные в виде линий, идеально подходят для этой ситуации, потому что они показывают ковариации двух переменных (в данном случае процент и временной промежуток). Как и в предыдущем примере, мы можем использовать группировку с помощью цвета.

 Различные варианты визуализации данных с примерами кода.
Пример графика. На нем показано процент степеней бакалавра, присвоенных женщинам в США (1970–2012)

Ниже представлен код для создания линейного графика. Он похож на код для программирования диаграммы рассеяния, рассмотренной выше, с некоторыми незначительными вариациями в переменных.

def lineplot(x_data, y_data, x_label="", y_label="", title=""):
    # Create the plot object
    _, ax = plt.subplots()

    # Plot the best fit line, set the linewidth (lw), color and
    # transparency (alpha) of the line
    ax.plot(x_data, y_data, lw = 2, color = '#539caf', alpha = 1)

    # Label the axes and provide a title
    ax.set_title(title)
    ax.set_xlabel(x_label)
    ax.set_ylabel(y_label)

Гистограммы (Histograms)

Гистограммы полезны для представления (или даже выявления) распределения данных. Посмотрите на пример ниже, где мы построили гистограмму частоты vs IQ. Мы легко можем заметить концентрацию ближе к центру, а также отчетливо прослеживается медиана значений. Мы также видим, что оно подчиняется гауссовскому распределению. Использование столбцов (а не точек рассеивания, например) действительно дает нам четкую визуализацию относительной разницы между частотой каждого интервала. Использование полос (интервалов = дискретизация) действительно помогает нам увидеть «целостную картину». Если эти же данные представить в виде отдельных точек, без выделения интервалов, то на диаграмме появится слишком много шума, что затруднит понимание тенденции, которая иллюстрируется с помощью этих данных.

 Различные варианты визуализации данных с примерами кода.
Пример гистограммы

Ниже приведен код гистограммы в Matplotlib. Обратите внимание на два параметра. Во-первых, параметры n_bins определяют, сколько отдельных интервалов нам необходимо поместить на нашей гистограмме. Большее число интервалов даст нам более точную информацию, но может также ввести информационный шум и отвлечь нас от понимания целостной картины; с другой стороны, меньшее число интервалов обеспечивает нам вид с высоты птичьего полёта и целостную картину того, что происходит, при этом не перегружая её мельчайшими деталями. Во-вторых, параметр cumulative является булевым (то есть 1 или 0), что позволяет нам выбрать, является ли наша гистограмма кумулятивной или нет. Другими словами, мы задаем либо плотность вероятности ( Probability Density Function (PDF)) либо функцию интегрального распределения ( Cumulative Density Function (CDF)).


def histogram(data, n_bins, cumulative=False, x_label = "", y_label = "", title = ""):
    _, ax = plt.subplots()
    ax.hist(data, n_bins = n_bins, cumulative = cumulative, color = '#539caf')
    ax.set_ylabel(y_label)
    ax.set_xlabel(x_label)
    ax.set_title(title)

Теперь представьте себе, что мы хотим сравнить распределение двух переменных в наших данных. Первая мысль, которая приходит в голову — это сделать две отдельные гистограммы и расположить их рядом, для наглядности. Но на самом деле есть способ лучше: мы можем накладывать гистограммы с различной прозрачностью. Посмотрите на рисунок, представленный ниже. Равномерное распределение имеет прозрачность 0,5, чтобы мы могли видеть, что расположено за ним. Это позволяет одновременно отобразить два распределения на одном рисунке.

 Различные варианты визуализации данных с примерами кода.
Наложение двух гистограмм: гауссовского и равномерного распределения

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

# Overlay 2 histograms to compare them
def overlaid_histogram(data1, data2, n_bins = 0, data1_name="", data1_color="#539caf", data2_name="", data2_color="#7663b0", x_label="", y_label="", title=""):
    # Set the bounds for the bins so that the two distributions are fairly compared
    max_nbins = 10
    data_range = [min(min(data1), min(data2)), max(max(data1), max(data2))]
    binwidth = (data_range[1] - data_range[0]) / max_nbins


    if n_bins == 0
    	bins = np.arange(data_range[0], data_range[1] + binwidth, binwidth)
    else: 
    	bins = n_bins

    # Create the plot
    _, ax = plt.subplots()
    ax.hist(data1, bins = bins, color = data1_color, alpha = 1, label = data1_name)
    ax.hist(data2, bins = bins, color = data2_color, alpha = 0.75, label = data2_name)
    ax.set_ylabel(y_label)
    ax.set_xlabel(x_label)
    ax.set_title(title)
    ax.legend(loc = 'best')

Столбчатые диаграммы (Bar Plots)

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

Обычная столбчатая диаграмма находится на первом рисунке снизу. В функции barplot() x_data задает метки на оси x, а y_data задает высоту столбца по оси y. Строка ошибки представляет собой дополнительную линию, расположенную в центре каждого столбца, которая может быть использована для отображения стандартного отклонения.

Сгруппированные столбчатые диаграммы позволяют сравнивать несколько переменных. Посмотрите на второй график снизу. Первой переменной, которую мы сравниваем, задается то, как оценки варьируются от группы к группе (группы G1, G2, … и так далее). Мы также сравниваем между собой распределение полов, что закодировано цветом. Теперь взгляните на код — вы заметите, что переменная y_data_list теперь фактически представляет собой список списков, где каждый вложенный список обозначает другую группу. Затем мы проходимся циклом по каждой группе, и для каждой группы рисуем столбец для каждого метки по оси x; все группы также дополнительно окрашиваются.

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

 Различные варианты визуализации данных с примерами кода.
Обычная столбчатая диаграмма. Использование языков программирования
 Различные варианты визуализации данных с примерами кода.
Сгруппированная столбчатая диаграмма. Распределение оценок по полу и возрасту
 Различные варианты визуализации данных с примерами кода.
Составная столбчатая диаграмм. Нагрузка на сервер по дням недели
def barplot(x_data, y_data, error_data, x_label="", y_label="", title=""):
    _, ax = plt.subplots()
    # Draw bars, position them in the center of the tick mark on the x-axis
    ax.bar(x_data, y_data, color = '#539caf', align = 'center')
    # Draw error bars to show standard deviation, set ls to 'none'
    # to remove line between points
    ax.errorbar(x_data, y_data, yerr = error_data, color = '#297083', ls = 'none', lw = 2, capthick = 2)
    ax.set_ylabel(y_label)
    ax.set_xlabel(x_label)
    ax.set_title(title)



def stackedbarplot(x_data, y_data_list, colors, y_data_names="", x_label="", y_label="", title=""):
    _, ax = plt.subplots()
    # Draw bars, one category at a time
    for i in range(0, len(y_data_list)):
        if i == 0:
            ax.bar(x_data, y_data_list[i], color = colors[i], align = 'center', label = y_data_names[i])
        else:
            # For each category after the first, the bottom of the
            # bar will be the top of the last category
            ax.bar(x_data, y_data_list[i], color = colors[i], bottom = y_data_list[i - 1], align = 'center', label = y_data_names[i])
    ax.set_ylabel(y_label)
    ax.set_xlabel(x_label)
    ax.set_title(title)
    ax.legend(loc = 'upper right')



def groupedbarplot(x_data, y_data_list, colors, y_data_names="", x_label="", y_label="", title=""):
    _, ax = plt.subplots()
    # Total width for all bars at one x location
    total_width = 0.8
    # Width of each individual bar
    ind_width = total_width / len(y_data_list)
    # This centers each cluster of bars about the x tick mark
    alteration = np.arange(-(total_width/2), total_width/2, ind_width)

    # Draw bars, one category at a time
    for i in range(0, len(y_data_list)):
        # Move the bar to the right on the x-axis so it doesn't
        # overlap with previously drawn ones
        ax.bar(x_data + alteration[i], y_data_list[i], color = colors[i], label = y_data_names[i], width = ind_width)
    ax.set_ylabel(y_label)
    ax.set_xlabel(x_label)
    ax.set_title(title)
    ax.legend(loc = 'upper right')

Прямоугольные диаграммы (Box Plots)

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

Вот здесь и вступают в игру прямоугольные диаграммы. Именно они помогают нам дополнительно разместить выше указанную информацию. Нижняя и верхняя части ящика, составленного сплошной линией, всегда являются первым и третьим квартилями (т.е. 25% и 75% данных), а полоса внутри прямоугольника всегда вторая квартиль (медиана). Усы (то есть пунктирные линии с полосками на конце) начинаются от прямоугольника и показывают диапазон данных.

Поскольку прямоугольные диаграммы строятся для каждой группы / переменной, их достаточно легко настраивать. x_data — это список групп / переменных. Функция Matplotlib boxplot() создает график для каждого столбца y_data или каждого вектора в последовательности y_data; таким образом, каждое значение в x_data соответствует столбцу / вектору в y_data. Все, что нам остается добавить, — это внешний вид графика.

 Различные варианты визуализации данных с примерами кода.
def boxplot(x_data, y_data, base_color="#539caf", median_color="#297083", x_label="", y_label="", title=""):
    _, ax = plt.subplots()

    # Draw boxplots, specifying desired style
    ax.boxplot(y_data
               # patch_artist must be True to control box fill
               , patch_artist = True
               # Properties of median line
               , medianprops = {'color': median_color}
               # Properties of box
               , boxprops = {'color': base_color, 'facecolor': base_color}
               # Properties of whiskers
               , whiskerprops = {'color': base_color}
               # Properties of whisker caps
               , capprops = {'color': base_color})

    # By default, the tick label starts at 1 and increments by 1 for
    # each box drawn. This sets the labels to the ones we want
    ax.set_xticklabels(x_data)
    ax.set_ylabel(y_label)
    ax.set_xlabel(x_label)
    ax.set_title(title)

Заключение

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

источник

+1
0
+1
0
+1
0
+1
0
+1
0

Ответить

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