Визуализация данных с Python-фреймворком Dash

Визуализация данных является неотъемлемой частью 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.

Заголовок и график Plotly в Dash
Веб-страница Dash

Добавляем данные

Выше мы составили очень простой линейный график, но в 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)
])
Заголовок и столбчатая диаграмма Plotly в Dash
Веб-страница Dash со столбчатой диаграммой

Обратные вызовы (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, как уже было сказано, это сам график.

В результате, мы получили график, который изменяется в зависимости от выбранного на слайдере года:

Интерактивный график Plotly в Dash
Веб-страница Dash с callback

Подобное использование декоратора, когда в ответ на изменение значения Input изменяется значения Output, называется Реактивным программированием. Его можно сравнить с созданием таблиц в MS Excel — когда значение одной ячейки изменяется, то вслед за ней обновляются зависимые ячейки. Реактивное программирование используется при создании пользовательских интрефейсов. Но имеет ограничение в виде значительной траты вычислительных ресурсов, поскольку нужно всегда следить за состоянием приложения.

 

В следующей статье поговорим о том, как в Dash работать со множеством Input и Output. А ещё больше подробностей о визуализации данных в Plotly и Dash для решения реальных задач Data Science, вы узнаете на специализированном курсе «VIP: Визуализация данных на языке Python» в лицензированном учебном центре обучения и повышения квалификации IT-специалистов в Москве.

Источники
  1. https://dash-gallery.plotly.host/dash-brain-viewer/
  2. https://dash-gallery.plotly.host/self-driving/
  3. https://dash-gallery.plotly.host/dash-word-arithmetic/

Добавить комментарий

Поиск по сайту