machinelearningmastery.ru

Машинное обучение, нейронные сети, искусственный интеллект
Header decor

Home

Визуализация данных с помощью Bokeh в Python, часть II: взаимодействия

Дата публикации Mar 20, 2018

Выход за пределы статических участков

впервая частьиз этой серии мы прошли через создание базовой гистограммы вBokeh, мощная библиотека визуализации Python. Окончательный результат, который показывает распределение задержек прилета рейсов, вылетающих из Нью-Йорка в 2013 году, показан ниже (с хорошей подсказкой!):

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

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

Весь код для этой сериидоступно на GitHub, Я призываю любого проверить все детали очистки данных (скучная, но необходимая часть науки о данных) и поэкспериментировать с кодом! (Для интерактивных графиков Боке мы все еще можем использовать Блокнот Jupyter, чтобы показать результаты, или мы можем писать сценарии Python и запускать сервер Bokeh. В процессе разработки я обычно работаю в блокноте Jupyter, потому что проще быстро выполнять итерации и изменять графики без перезапуска сервера. Затем я перехожу на сервер для отображения окончательных результатов. см. как отдельный скрипт, так и полную записную книжку на GitHub.)

Активные взаимодействия

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

Подсказка, пассивный интерактор

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

Пример виджетов (выпадающая кнопка и группа переключателей)

Когда я смотрю графики, мне нравится играть с активными взаимодействиями (такие как те на FlowingData) потому что они позволяют мне самостоятельно исследовать данные. Я нахожу более проницательным находить выводы из данных самостоятельно (с некоторым указанием дизайнера), а не из полностью статичной диаграммы. Более того, предоставление пользователям некоторой свободы дает им немного другие интерпретации, которые могут привести к полезной дискуссии о наборе данных.

План взаимодействия

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

  • make_dataset()Отформатируйте конкретные данные для отображения
  • make_plot()Нарисуйте участок с указанными данными
  • update() Обновите график на основе выбора пользователя

Форматирование данных

Прежде чем мы сможем построить график, нам нужно спланировать данные, которые будут отображаться. Для нашей интерактивной гистограммы мы предложим пользователям три контролируемых параметра:

  1. Отображаются авиакомпании (в коде называются перевозчики)
  2. Диапазон задержек на сюжете, например: от -60 до +120 минут
  3. Ширина ячейки гистограммы, по умолчанию 5 минут

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

Данные для гистограммы

В этом наборе данных каждый ряд представляет собой отдельный полет.arr_delayстолбец - задержка прибытия рейса в минутах (отрицательные числа означают, что рейс был ранним) В части I мы провели некоторое исследование данных и знаем, что существует 327 236 рейсов с минимальной задержкой -86 минут и максимальной задержкой +1272 минуты. вmake_datasetфункция, мы хотим выбрать авиакомпании на основеnameстолбец в кадре данных и ограничить полетыarr_delayколонка.

Чтобы сделать данные для гистограммы, мы используем функцию numpyhistogramкоторый подсчитывает количество точек данных в каждом бине. В нашем случае это количество рейсов за каждый указанный интервал задержки Для части I мы составили гистограмму для всех рейсов, но теперь мы будем делать это для каждого перевозчика. Поскольку количество рейсов для каждого перевозчика значительно варьируется, мы можем отображать задержки не в необработанном количестве, а в пропорциях. То есть высота на графике соответствует доле всех рейсов для конкретной авиакомпании с задержкой в ​​соответствующем бункере. Чтобы перейти от количества к пропорции, мы делим счет на общее количество для авиакомпании.

Ниже приведен полный код для создания набора данных. Функция принимает список операторов, которые мы хотим включить, минимальные и максимальные задержки, которые будут отображаться, и указанную ширину бина в минутах.

(Я знаю, что это пост о Bokeh, но вы не можете сделать график без отформатированных данных, поэтому я включил код, чтобы продемонстрировать мои методы!)

Результаты запуска функции со всеми носителями приведены ниже:

Напоминаем, что мы используем Bokehquadглифы для создания гистограммы, поэтому нам нужно указать левую, правую и верхнюю части глифа (нижняя часть будет зафиксирована на 0). Это вleft,right, а такжеproportionстолбцы соответственно. Колонка цвета дает каждому носителю уникальный цвет иf_столбцы предоставляют форматированный текст для всплывающих подсказок.

Следующая функция для реализацииmake_plot, Функция должна принимать в ColumnDataSource(определенный тип объекта, используемый в Bokeh для построения графика)и вернуть сюжетный объект:

Если мы передаем источник со всеми авиакомпаниями, этот код дает нам следующий график:

Эта гистограмма очень перегружена, потому что на одном графике изображены 16 авиакомпаний! Если мы хотим сравнить авиакомпании, это практически невозможно из-за дублирования информации. К счастью, мы можем добавить виджеты, чтобы сделать график более понятным и обеспечить быстрое сравнение

Создание взаимодействий виджетов

Как только мы создадим базовую фигуру в Bokeh, добавление взаимодействий через виджеты будет относительно простым. Первый виджет, который нам нужен, это поле выбора, которое позволяет зрителям выбирать авиакомпании для отображения. Этот элемент управления будет флажок, который позволяет столько вариантов, сколько нужно, и известен в Боке какCheckboxGroup.Чтобы сделать инструмент выбора, мы импортируемCheckboxGroupКласс и создать экземпляр с двумя параметрами,labels: значения, которые мы хотим отобразить рядом с каждым полем иactive: начальные поля, которые отмечены. Вот код для созданияCheckboxGroupсо всеми перевозчиками.

from bokeh.models.widgets import CheckboxGroup# Create the checkbox selection element, available carriers is a  
# list of all airlines in the data
carrier_selection = CheckboxGroup(labels=available_carriers,
active = [0, 1])
CheckboxGroup виджет

Метки в флажке Bokeh должны быть строками, а активные значения - целыми числами. Это означает, что на изображении «AirTran Airways Corporation» отображается на активное значение 0, а «Alaska Airlines Inc.» отображается на активное значение 1. Когда мы хотим сопоставить выбранные флажки с авиакомпаниями, мы должны убедиться, что найтистрокаимена, связанные с выбраннымцелое числоактивные значения. Мы можем сделать это с помощью.labelsа также.active атрибуты виджета:

# Select the airlines names from the selection values
[carrier_selection.labels[i] for i in carrier_selection.active]['AirTran Airways Corporation', 'Alaska Airlines Inc.']

После создания виджета выбора нам нужно связать флажки выбранной авиакомпании с информацией, отображаемой на графике. Это достигается с помощью.on_changeметод CheckboxGroup иupdateфункция, которую мы определяем. Функция обновления всегда принимает три аргумента:attr, old, newи обновляет график на основе элементов управления выбором. Мы изменяем данные, отображаемые на графике, путем изменения источника данных, который мы передали глифу (ам) вmake_plotфункция. Это может звучать немного абстрактно, так что вот примерupdateфункция, которая изменяет гистограмму для отображения выбранных авиакомпаний:

# Update function takes three default parameters
def update(attr, old, new):
# Get the list of carriers for the graph
carriers_to_plot = [carrier_selection.labels[i] for i in
carrier_selection.active] # Make a new dataset based on the selected carriers and the
# make_dataset function defined earlier
new_src = make_dataset(carriers_to_plot,
range_start = -60,
range_end = 120,
bin_width = 5) # Update the source used in the quad glpyhs
src.data.update(new_src.data)

Здесь мы получаем список авиакомпаний для отображения на основе выбранных авиакомпаний из CheckboxGroup. Этот список передаетсяmake_datasetфункция, которая возвращает новый источник данных столбца. Мы обновляем данные источника, используемого в глифах, вызываяsrc.data.updateи передача данных из нового источника. Наконец, чтобы связать изменения вcarrier_selectionвиджет дляupdateфункция, мы должны использовать.on_change метод (называетсяобработчик события).

# Link a change in selected buttons to the update function
carrier_selection.on_change('active', update)

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

Больше элементов управления

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

Стандартный слайдер и слайдер диапазона показаны здесь:

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

# Change plot title to match selection
bin_width = binwidth_select.value
p.title.text = 'Delays with %d Minute Bin Width' % bin_width

В Bokeh есть много других типов взаимодействий, но пока наши три элемента управления позволяют пользователям много «играть» на графике!

Собираем все вместе

Все элементы нашего интерактивного сюжета на месте. У нас есть три необходимые функции:make_dataset,make_plot, а такжеupdateизменить сюжет на основе элементов управления и самих виджетов. Мы объединяем все эти элементы на одной странице, определяя макет.

from bokeh.layouts import column, row, WidgetBox
from bokeh.models import Panel
from bokeh.models.widgets import Tabs# Put controls in a single element
controls = WidgetBox(carrier_selection, binwidth_select, range_select)

# Create a row layout
layout = row(controls, p)

# Make a tab with the layout
tab = Panel(child=layout, title = 'Delay Histogram')
tabs = Tabs(tabs=[tab])

Я помещаю весь макет на вкладку, и когда мы создаем полное приложение, мы можем поместить каждый график на отдельную вкладку. Окончательный результат всей этой работы ниже:

Не стесняйтесь проверить код и построить для себя наGitHub,

Следующие шаги и выводы

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

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

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

Оригинальная статья

Footer decor

© machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map