Дата публикации Mar 20, 2018
Выход за пределы статических участков
впервая частьиз этой серии мы прошли через создание базовой гистограммы вBokeh, мощная библиотека визуализации Python. Окончательный результат, который показывает распределение задержек прилета рейсов, вылетающих из Нью-Йорка в 2013 году, показан ниже (с хорошей подсказкой!):
Этот график выполняет свою работу, но он не очень привлекателен! Зрители могут видеть, что распределение задержек в полете почти нормальное (с небольшим положительным перекосом), но у них нет причин тратить больше чем несколько секунд с этой цифрой.
Если мы хотим создать более привлекательную визуализацию, мы можем позволить пользователям самостоятельно исследовать данные с помощью взаимодействий. Например, в этой гистограмме одной ценной функцией будет возможность выбора конкретных авиакомпаний для сравнения или возможность изменения ширины ячеек для более детального изучения данных. К счастью, обе эти функции мы можем добавить поверх нашего существующего сюжета, используя Bokeh. Первоначальное развитие гистограммы могло показаться простым сюжетом, но теперь мы увидим отдачу от использования мощной библиотеки, такой как Bokeh!
Весь код для этой сериидоступно на GitHub, Я призываю любого проверить все детали очистки данных (скучная, но необходимая часть науки о данных) и поэкспериментировать с кодом! (Для интерактивных графиков Боке мы все еще можем использовать Блокнот Jupyter, чтобы показать результаты, или мы можем писать сценарии Python и запускать сервер Bokeh. В процессе разработки я обычно работаю в блокноте Jupyter, потому что проще быстро выполнять итерации и изменять графики без перезапуска сервера. Затем я перехожу на сервер для отображения окончательных результатов. см. как отдельный скрипт, так и полную записную книжку на GitHub.)
В Боке есть два класса взаимодействий: пассивный и активный. Пассивные взаимодействия, описанные в части I, также известны как инспекторы, поскольку они позволяют пользователям более детально изучить график, но не изменяют отображаемую информацию. Одним из примеров является всплывающая подсказка, которая появляется, когда пользователь наводит курсор на точку данных:
Второй класс взаимодействия называется активным, поскольку он изменяет фактические данные, отображаемые на графике. Это может быть что угодно, от выбора подмножества данных (например, конкретных авиакомпаний) до изменения степени соответствия полиномиальной регрессии. Есть несколько типовактивные взаимодействия в боке, но здесь мы сосредоточимся на так называемых «виджетах», элементах, по которым можно щелкнуть и которые дают пользователю контроль над некоторыми аспектами сюжета.
Когда я смотрю графики, мне нравится играть с активными взаимодействиями (такие как те на FlowingData) потому что они позволяют мне самостоятельно исследовать данные. Я нахожу более проницательным находить выводы из данных самостоятельно (с некоторым указанием дизайнера), а не из полностью статичной диаграммы. Более того, предоставление пользователям некоторой свободы дает им немного другие интерпретации, которые могут привести к полезной дискуссии о наборе данных.
Как только мы начинаем добавлять активные взаимодействия, нам нужно выйти за пределы отдельных строк кода и перейти к функциям, которые инкапсулируют конкретные действия. Для взаимодействия с виджетом Bokeh существуют три основные функции, которые необходимо реализовать:
make_dataset()
Отформатируйте конкретные данные для отображенияmake_plot()
Нарисуйте участок с указанными даннымиupdate()
Обновите график на основе выбора пользователяПрежде чем мы сможем построить график, нам нужно спланировать данные, которые будут отображаться. Для нашей интерактивной гистограммы мы предложим пользователям три контролируемых параметра:
Для функции, которая создает набор данных для графика, нам нужно разрешить указывать каждый из этих параметров. Чтобы сообщить, как мы будем преобразовывать данные в нашем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])
Метки в флажке 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,
© machinelearningmastery.ru | Ссылки на оригиналы и авторов сохранены. | map