Визуализация данных с помощью веб-фреймворка Dash
Python и 1000 программ
Сам по себе фреймворк это некая смесь HTML, React, Js, Flask и CSS и предоставляет python классы для всех своих визуальных компонентов.
Уйдет достаточно много времени на предоставление всех функций веб фреймворка 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 - это уникальный идентификатор объекта, который нам понадобится, когда нам придется описывать логику. По коду можно понять, что функционал этого объекта можно описать через словарь.
Далее добавляем графический объект.
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 объекта и его значения, которые были описаны в словаре атрибута option. 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)
Надеюсь в моей статье вы осознали невероятное множество функций и вариантов применения при помощи данного фреймворка. Удачи вам в программирование!