Как стать автором
Обновить

Визуализация данных с помощью веб-фреймворка Dash

Время на прочтение4 мин
Количество просмотров10K

Dash является довольно интересным Веб-фреймворком для визуализации данных и имеет в семе довольно много полезных функций в сочетании с простотой их применения.

Сам Dash это некий коллаб  HTML, React.Js, Flask  и CSS и предоставляет python классы для всех своих визуальных компонентов.

В качестве демонстративного датасета я возьму датасет diamonds с сайта kaggle (https://www.kaggle.com/shivam2503/diamonds)

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

Привожу пример сэмпла датасета

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
from dash.dependencies import Input, Output

Для начала отметим что работу в dash  можно разделить на две части внешнюю(layout) то есть создание визуальной составляющей дашборда, и внутреннюю(callbacks) в которых мы описываем логику взаимодействия с объектами на дашборде.

В начале инициализируем класс dash, а также подгружаем dataset

app = dash.Dash(__name__)
df  = pd.read_csv('C://Users//User//Desktop//Учеба//diam.csv',sep = ';')

Далее создадим заголовок.

Для более красивого отображения, я использовал эти стили (https://github.com/matyushkin/lessons/blob/master/visualization/dash/avocado_analytics/apps/app_2/assets/style.css)

Определяем компонент html.Div а также вносим в него заголовок(html.h1) и абзац(html.P)

app.layout = html.Div(children=[

    html.Div(
        children=[
            html.H1(children='Analysis diamonds dataset', className= 'header-title'),


            html.P(children='maybe this demo will be useful to someone (:', className= 'header-description')и 
                ], className= 'header')])

ClassName является ссылкой на css файл

Который можно подгрузить внутрь проекта создав для него папку assets.

Вид структуры должен быть подобный

И запустим наше приложение

if __name__ == '__main__':
    app.run_server(debug=True)

Заголовок готов, теперь можно приступить к созданию объекта dropdown

Это будет меню для выбора необходимой гистограммы.

 

Данный элемент в коде будет выглядеть вот так

html.Div([
    dcc.Dropdown(
        id='demo_drop',
        options=[
            {'label': 'Огранка', 'value': 'cut'},
            {'label': 'Ясность(чистота)', 'value': 'clarity'},
            {'label': 'Цвет', 'value': 'color'}
        ],
        value='cut', className="dropdown"
    )])

В данном случае id означает уникальный идентификатор объекта он нам понадобится, когда будем описывать логику. Как можно понять из кода функционал данного объекта можно описать через словарь.  Атрибут value означает дефолтное выбранное значение.

Далее добавляем графический объект

dcc.Graph(id='output_graph')],className="card")

Пока что он пуст, но это только пока.

Далее нам нужно сделать так что бы наше приложение реагировало на запрос пользователя и для этого нужно использовать функции обратного вызова.  В них и будет описана связь между объектами Dropdown  и graph.

@app.callback(
 	   Output(component_id='output_graph', component_property='figure'),
    [	Input(component_id='demo_drop', component_property='value')]
)

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

А output возвращает гистограмму и ее значения.

Остается только прописать логику для обработки информации.

Что бы понять сколько было драгоценных камней для каждого уровня огранки, нужно сгруппировать данные по уровням огранки и вычислить количество строк внутри группы.

Для pandas это будет выглядеть вот так

h = df.groupby(['cut'], as_index=False, sort=False)['carat'].count()

Теперь вплетаем данное вычисление в функцию

def update_output(value):
    	if value == 'cut':
        		h = df.groupby(['cut'], as_index=False, sort=False)['carat'].count()
    	elif value == 'clarity':
        		h = df.groupby(['clarity'], as_index=False, sort=False)['carat'].count()
    	elif value == 'color':
        		h = df.groupby(['color'], as_index=False, sort=False)['carat'].count()
    	fig = px.bar(h, x=value, y="carat", labels = {"carat" : "Count"} )
    	 return fig

То есть если описывать, то каждая вариация выбора пользователя связана со значением, которое используется в алгоритме.

А переменная fig создает гистограмму

Таким образом у нас выходит такого вида интерфейс с выбором параметра группировки

Итоговый код

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
from dash.dependencies import Input, Output

 
app = dash.Dash(__name__)
df  = pd.read_csv('C://Users//User//Desktop//Учеба//diam.csv',sep = ';')
 
 
app.layout = html.Div(children=[


 
    html.Div(
        children=[
            html.H1(children='Analysis diamonds dataset', className= 'header-title'),
 

            html.P(children='maybe this demo will be useful to someone (:', className= 'header-description')
                ], className= 'header'),
 
    #html.Label('Количество'),
    html.Div([
        dcc.Dropdown(
            id='demo_drop',
            options=[
                {'label': 'Огранка', 'value': 'cut'},
                {'label': 'Ясность(чистота)', 'value': 'clarity'},
                {'label': 'Цвет', 'value': 'color'}
            ],
            value='cut', className="dropdown"
        ),  dcc.Graph(id='output_graph')],className="card")
 
])
@app.callback(
    Output(component_id='output_graph', component_property='figure'),
    [Input(component_id='demo_drop', component_property='value')]
)
def update_output(value):
    if value == 'cut':
        h = df.groupby(['cut'], as_index=False, sort=False)['carat'].count()
    elif value == 'clarity':
        h = df.groupby(['clarity'], as_index=False, sort=False)['carat'].count()
    elif value == 'color':
        h = df.groupby(['color'], as_index=False, sort=False)['carat'].count()
    fig = px.bar(h, x=value, y="carat", labels = {"carat" : "Count"} )
    return fig
 
if __name__ == '__main__':
    app.run_server(debug=True)

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

Теги:
Хабы:
Всего голосов 3: ↑3 и ↓0+3
Комментарии10

Публикации

Истории

Работа

Data Scientist
61 вакансия
Python разработчик
122 вакансии

Ближайшие события

One day offer от ВСК
Дата16 – 17 мая
Время09:00 – 18:00
Место
Онлайн
Конференция «Я.Железо»
Дата18 мая
Время14:00 – 23:59
Место
МоскваОнлайн
Антиконференция X5 Future Night
Дата30 мая
Время11:00 – 23:00
Место
Онлайн
Конференция «IT IS CONF 2024»
Дата20 июня
Время09:00 – 19:00
Место
Екатеринбург
Summer Merge
Дата28 – 30 июня
Время11:00
Место
Ульяновская область