Визуализация данных является неотъемлемой частью Data Science. И сегодня мы поговорим о фреймворке визуализации данных на Python — Dash, который позволяет работать не только с интерактивными графиками, но и выводить их на веб-сайт. Читайте у нас: инициализация приложения, работа с графиками и данными, а также использование обратных вызовов (callback) в Dash.
Что такое Dash
Dash — это фреймворк для построения веб-приложений на Python. Он написан с использованием Flask, React.js, Plotly.js и является инструментом для интерактивной визуализации, которую можно интегрировать в веб-сайт. При этом для работы с ним не требуются знания ни Flask, ни React, ни JavaScript.
Зная только Python, некоторые тэги HTML и базовые графики Plotly, можно реализовать разные проекты по визуализации данных в рамках Data Science, например:
- 3D-изображение мозга человека [1],
- детектирование объектов на изображении на основе методов глубокого обучения (Deep Learning) [2],
- диаграммы word embeddings [3] и многое другое.
Установить Dash можно с помощью пакетного менеджера Pip, который дополнительно установит такие зависимости как Plotly и Flask:
pip install dash
Простое Dash-приложение
Напишем свое первое приложение с Dash. Ниже представлен код на Python, который нужно сохранить в отдельном файле и запустить его через терминал. Запускается приложение как обычный Python-файл: python my_file.py
. После запуска будет выведен адрес, по которому нужно перейти через браузер.
import dash import dash_html_components as html app = dash.Dash('my_first_app') app.layout = html.H1('Hello') app.run_server(debug=True)
Это приложение лишь выводит на веб-странице слово Hello. Разберемся с кодом:
- Инициализация приложение осуществляется через
dash.Dash
, где мы указываем название приложения; - Атрибут
layout
определяет, что будет на веб-странице. Здесь мы указали, что на странице будет отображён только заголовок h1 (тэг <h1>). Все компоненты HTML находятся в модулеdash_html_components
; - Запускается приложение через
run_server.
Мы установилиdebug=True
, чтобы иметь возможность отладить код. В случае если приложение готово для работы на сервере, то, в целях безопасности, флаг следует поставить в значение False.
Добавляем график
Поскольку Dash — веб-фреймворк для визуализации данных, добавим в наше приложение график. В модуле dash_core_components
есть класс Graph
, который отвечает за работу с диаграммами Plotly. Воспользуемся им, тогда Python-код будет выглядеть следующим образом:
import dash_core_components as dcc app = dash.Dash('my_first_app') app.layout = html.Div([ html.H1('Hello'), Graph( figure={ 'data': [ {'x': [1, 2], 'y': [3, 1]} ] }, ) ]) app.run_server(debug=True)
В тэге <div> будут располагаться заголовок h1 и график Plotly.
Добавляем данные
Выше мы составили очень простой линейный график, но в Data Science проектах часто приходится сталкиваться с данными, которые требуют разные виды диаграмм. Сымитируем данные с помощью Python-библиотеки Pandas, а затем построим столбчатую диаграмму с помощью Plotly. Чтобы построить столбчатую диаграмму, воспользуемся функцией bar
из модуля plotly.express
:
import plotly.express as px import pandas as pd df = pd.DataFrame({ "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"], "Amount": [4, 1, 2, 2, 4, 5], "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"] }) fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")
Отображение остаётся все тем же: в тэге <div> будет находится заголовок h1 и столбчатая диаграмма, которую мы создали из наших данных:
app.layout = html.Div([ html.H1('Hello'), dcc.Graph(figure=fig) ])
Обратные вызовы (callbacks)
Главной особенностью Dash являются обратные вызовы (callbacks). В примере выше данные остаются неизменными, но в Data Science данные могут быть самыми разнообразными: показатели могут меняются в зависимости от атрибутов или данные могут обновляться с каждым днем и т.д. С таким видом данных в Dash можно работать, используя лишь специальный декоратор @app.callback
, где app
— название переменной приложения (во всех примерах выше мы называли её app
).
Возьмем для примера датасет от Plotly, который содержит данные об ожидаемой продолжительности жизни в странах в разные периоды. А на веб-странице отобразим график и слайдер. Слайдер будет находиться в пределах минимального и максимального года, и в зависимости от текущего года на слайдере будет меняться соответственно график. Начальное значение слайдера определяется минимальным годом. У графика и слайдера будут уникальные идентификаторы (id), которые пригодятся в дальнейшем. Python-код выглядит следующим образом:
df = pd.read_csv('https://raw.githubusercontent.com/plotly/datasets/master/gapminderDataFiveYear.csv') app = dash.Dash('app') app.layout = html.Div([ dcc.Graph(id='my-graph'), dcc.Slider( id='year-slider', min=df['year'].min(), max=df['year'].max(), value=df['year'].min(), marks={str(year): str(year) for year in df['year'].unique()}, step=None ) ])
Теперь создадим функцию, внутри которой будем определять форму графика (scatter). Эта функция будет соответственно задекорирована:
from dash.dependencies import Input, Output import plotly.express as px @app.callback( Output('my-graph', 'figure'), [Input('year-slider', 'value')]) def update_figure(selected_year): filtered_df = df[df.year == selected_year] fig = px.scatter(filtered_df, x="gdpPercap", y="lifeExp", size="pop", color="continent", hover_name="country", log_x=True, size_max=55) return fig
Отметим основные положения:
- Декоратор имеет
Output
(выход),Input
(вход) из модуляdash.dependencies
.Input
принимает входной id и его значение, в нашем случае это id слайдера (year-slider
), а значение — это год.Ouput
принимает выходной id и его значение, в нашем случае это id графика (my-graph
), а значение — сам график; - Декорируемая функция может иметь любое название и должна принимать столько аргументов, сколько значений в
Input
указано. В нашем случаеInput
имеет входное значение — выбранный на слайдере год; - Внутри декорируемой функции выбираются данные с выбранным годом на слайдере и строится график (scatter);
- Декорируемая функция должна возвращать значение
Output
, как уже было сказано, это сам график.
В результате, мы получили график, который изменяется в зависимости от выбранного на слайдере года:
Подобное использование декоратора, когда в ответ на изменение значения Input изменяется значения Output, называется Реактивным программированием. Его можно сравнить с созданием таблиц в MS Excel — когда значение одной ячейки изменяется, то вслед за ней обновляются зависимые ячейки. Реактивное программирование используется при создании пользовательских интрефейсов. Но имеет ограничение в виде значительной траты вычислительных ресурсов, поскольку нужно всегда следить за состоянием приложения.
В следующей статье поговорим о том, как в Dash работать со множеством Input и Output. А ещё больше подробностей о визуализации данных в Plotly и Dash для решения реальных задач Data Science, вы узнаете на специализированном курсе «VIP: Визуализация данных на языке Python» в лицензированном учебном центре обучения и повышения квалификации IT-специалистов в Москве.