Dashboard на python вместо excel

Время на прочтение
8 мин

Количество просмотров 6.4K

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

Если речь идет о данных, значит, это касается и Python. В частности, мы говорим о библиотеке Dash, которая построена на базе одной из самых популярных библиотек для построения графиков — Plotly.

Dash позволяет легко создавать и делиться результатами анализа данных с помощью интерактивных дашбордов, используя только код Python. Нет необходимости изучать HTML, CSS или сложные JavaScript-фреймворки, такие как React.js.

В этом руководстве вы получите представление о том, на что способен Dash, и как интегрировать его в свой рабочий процесс.

Установка Dash и Plotly

Вы можете установить Dash с помощью pip. Также необходимо инсталлировать библиотеку pandas для работы с наборами данных:

pip install dash pandas

Приведенная выше команда также выполняет установку plotly. Plotly известен своими интерактивными графиками, и Plotly и Dash созданы Plotly Software Foundation, поэтому библиотеки довольно хорошо работают вместе.

Требования по использованию Dash

У такого мощного фреймворка, как Dash, есть несколько требований. Во-первых, вы должны знать Plotly Python, поскольку Dash может отображать только интерактивные графики Plotly.

Далее, вам необходимо базовое понимание HTML и CSS. Dash похож на React, но на языке Python. Это шаблонный фреймворк, на котором вы можете создать сайт без JavaScript.

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

Создание Dash-приложения 

Давайте создадим наше Dash-приложение. После инсталляции импортируем следующие библиотеки:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd

dash – это глобальная библиотека, содержащая все основные функции. dash_core_components и dash_html_components – это библиотеки, которые устанавливаются с dash по умолчанию. Они включают специфические для Dash фичи и Python-представление HTML-компонентов (тегов). Подробнее о них позже.

Любое приложение Dash запускается с помощью следующей команды:

app = dash.Dash(name="my_first_dash_app")

>>> app
<dash.dash.Dash at 0x1ee6af51af0>

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

Сначала мы загрузим встроенный датасет из Plotly и создадим простую диаграмму рассеяния:

# Load dataset using Plotly
tips = px.data.tips()

fig = px.scatter(tips, x="total_bill", y="tip") # Create a scatterplot

Затем мы добавляем это изображение в атрибут layout нашего приложения внутри тега div с небольшими текстами:

app.layout = html.Div(children=[
   html.H1(children='Hello Dash'),  # Create a title with H1 tag

   html.Div(children='''
       Dash: A web application framework for your data.
   '''),  # Display some text

   dcc.Graph(
       id='example-graph',
       figure=fig
   )  # Display the Plotly figure
])

if __name__ == '__main__':
   app.run_server(debug=True) # Run the Dash app

Теперь мы создаем HTML-теги с помощью библиотеки dash_html_components (html), а изображение – используя основные компоненты (dcc) library .

За тегом заголовка H1 следует div, содержащий обычный текст, затем сам график с использованием функции Graph библиотеки dcc. Все это находится внутри атрибута children одного тега DIV.

В конце мы также добавляем команду, которая запускает наше приложение в режиме отладки, то есть изменения вступают в силу по мере внесения поправок в скрипт. Вот полный код на данный момент:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd

# Create the app
app = dash.Dash(__name__)

# Load dataset using Plotly
tips = px.data.tips()

fig = px.scatter(tips, x="total_bill", y="tip") # Create a scatterplot

app.layout = html.Div(children=[
   html.H1(children='Hello Dash'),  # Create a title with H1 tag

   html.Div(children='''
       Dash: A web application framework for your data.
   '''),  # Display some text

   dcc.Graph(
       id='example-graph',
       figure=fig
   )  # Display the Plotly figure
])

if __name__ == '__main__':
   app.run_server(debug=True) # Run the Dash app

Поместите его в скрипт Python и запустите. В терминале вы получите сообщение о том, что необходимо перейти по этой ссылке: http://127.0.0.1:8050/.

Итак, поехали:

В следующих разделах мы подробно расскажем о том, что здесь произошло.


Создание app.layout

Давайте начнем с атрибута layout. Это единственный атрибут, который содержит все ваши HTML-компоненты и изображения. Вы должны передать ему всю вашу графику и HTML-теги в конечном теге DIV.

В зависимости от размера вашего проекта, данный атрибут может стать довольно большим, поэтому я рекомендую создавать все ваши HTML-теги и фигуры в отдельных переменных, а затем передавать их в layout.

Например, вот как будет выглядеть приведенное выше приложение:

app = dash.Dash(name="app")

# Load dataset using Plotly
tips = px.data.tips()

fig = px.scatter(tips, x="total_bill", y="tip")  # Create a scatterplot

title = html.H1("Hello Dash!")
text_div = html.Div("Dash: A web application framework for your data.")
graph_to_display = dcc.Graph(id="scatter", figure=fig)

app.layout = html.Div(children=[title, text_div, graph_to_display])

Это гораздо аккуратнее и компактнее, и это одна из тех вещей, о которых вы не узнаете в документации Dash. Там куча вложенного кода вместо того, чтобы сделать вышеописанное.

Компоненты HTML и CSS в Dash

Давайте обсудим, как HTML и CSS работают в Dash. Подбиблиотека dash_html_components содержит наиболее распространенные теги HTML, такие как divs, кнопки, текстовые поля, названия, теги заголовков (H1-6) и т. д.

Они реализованы в коде Python под соответствующими именами как представление их HTML-аналогов. Итак, код, подобный приведенному, ниже:

import dash_html_components as html

html.Div([
   html.H1('Hello Dash'),
   html.Div([
       html.P('Dash converts Python classes into HTML'),
       html.P("This conversion happens behind the scenes by Dash's JavaScript frontend")
   ])
])

Будет интерпретироваться вашим браузером следующим образом:

<div>
   <h1>Hello Dash</h1>
   <div>
       <p>Dash converts Python classes into HTML</p>
       <p>This conversion happens behind the scenes by Dash's JavaScript front-end</p>
   </div>
</div>

Все HTML-теги этой подбиблиотеки содержат следующие основные аргументы:

  • id: то же, что и атрибут id HTML-тегов

  • className: то же самое, что и атрибут class тегов HTML

  • style: такой же, как атрибут style тегов HTML, но принимает только словарь стилей CSS

  • children: первый аргумент большинства компонентов HTML

Вот пример div с некоторыми кастомизированными настройками:

app = dash.Dash(name="app")

app.layout = html.Div(
   children=html.H3("Simple Div"),
   id="sample_div",
   className="red_div",
   style={"backgroundColor": "red"},
)

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

Аргумент children уникален — он может принимать числа и строки, но чаще всего вы передаете другие компоненты HTML списком, если это тег-контейнер, например такой как div.

Замечание о стилях CSS: большинство атрибутов стиля CSS используют дефисы для разделения слов. Когда вы передаете их в аргумент style Dash, они должны применять camelCase, например backgroundColor вместо background-color.

Я настоятельно рекомендую вам изучить данные HTML-теги, поскольку это единственное, что сохраняет целостность макета (лейаута) вашего приложения. Вот полный список HTML-тегов, поддерживаемых Dash.

Основные компоненты Dash

Другой важной частью Dash являются его основные компоненты. Библиотека dash_core_components содержит несколько других HTML-тегов, но в нее уже встроено немного CSS и JavaScript.

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

Вот несколько образцов этих компонентов, начиная с выпадающего списка:

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
   dcc.Dropdown(
       options=[
           {'label': 'FC Barcelona', 'value': 'FCB'},
           {'label': 'Real Madrid', 'value': 'RM'},
           {'label': 'Manchester United', 'value': 'MU'}
       ],
       value='FCB' # The default value to display
   )
])

Выпадающий список с мультивыбором:

app = dash.Dash(__name__)

app.layout = html.Div([
   dcc.Dropdown(
       options=[
           {'label': 'FC Barcelona', 'value': 'FCB'},
           {'label': 'Real Madrid', 'value': 'RM'},
           {'label': 'Manchester United', 'value': 'MU'}
       ],
       multi=True,
       value="FCB"
   )
], style={"width": 200})

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

Слайдер с помеченными точками останова:

import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash(__name__)

app.layout = html.Div([
   dcc.Slider(
       min=0,
       max=9,
       marks={i: 'Label{}'.format(i) for i in range(10)},
       value=5,
   )
])

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

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

Полный список основных компонентов можно посмотреть здесь.

Создание финального интерфейса визуализации данных с помощью Python Dash

В качестве завершающего примера посмотрите на приведенное ниже приложение:

import seaborn as sns

app = dash.Dash(__name__)

diamonds = sns.load_dataset("diamonds")

scatter = px.scatter(
   data_frame=diamonds,
   x="price",
   y="carat",
   color="cut",
   title="Carat vs. Price of Diamonds",
   width=600,
   height=400,
)
histogram = px.histogram(
   data_frame=diamonds,
   x="price",
   title="Histogram of Diamond prices",
   width=600,
   height=400,
)
violin = px.violin(
   data_frame=diamonds,
   x="cut",
   y="price",
   title="Violin Plot of Cut vs. Price",
   width=600,
   height=400,
)

left_fig = html.Div(children=dcc.Graph(figure=scatter))
right_fig = html.Div(children=dcc.Graph(figure=histogram))

upper_div = html.Div([left_fig, right_fig], style={"display": "flex"})
central_div = html.Div(
   children=dcc.Graph(figure=violin),
   style={"display": "flex", "justify-content": "center"},
)
app.layout = html.Div([upper_div, central_div])

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

Мы импортируем датасет Diamonds из Seaborn и создаем три графика: диаграмму рассеяния, гистограмму и скрипичную диаграмму. Мы хотим отобразить график рассеяния и гистограмму рядом друг с другом и поместить скрипичную диаграмму прямо под ними в центре.

Для этого мы создаем два div’а, содержащих график рассеяния и гистограмму, left_figure и right_figure. Затем для простоты эти два div помещаем в еще один div — upper_div.

Мы устанавливаем CSS-стиль flex-box для этого div, который размещает фигуры бок о бок.

Затем мы создаем центральный div, содержащий скрипичную диаграмму, и выравниваем его по центру с помощью flex-box и его атрибута justify-content.

Наконец, мы помещаем все в лейаут внутри последнего DIV и запускаем скрипт. Вот конечный результат:

Заключение

Вот краткое описание шагов по созданию базового Dash-приложения:

  1. Создайте приложение с помощью dash.Dash и дайте ему любое название.

  2. Набросайте лейаут своих графиков в дашборде, прежде чем писать код.

  3. Создайте графики, которые войдут в ваш дашборд

  4. Создайте шаблонный лейаут с помощью HTML-компонентов Dash

  5. Добавьте свои изображеня в соответствующие контейнеры

  6. Наконец, добавьте все HTML-компоненты к атрибуту лейаута

Несмотря на то, что мы рассмотрели многие базовые аспекты, такие как HTML, основные компоненты и лейаут приложения, это лишь поверхностное знакомство с возможностями Dash.

Я показал вам множество примеров интерактивных HTML-компонентов, но не рассказал, как интегрировать их в ваше приложение. Как вы можете обновлять графики на основе вводимых пользователем данных, таких как слайдеры, текст или что-то подобное?

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

Dash посвящает большой раздел в документации только для объяснения коллбеков, поскольку поначалу в них трудно разобраться. Я предлагаю вам обратиться к этой теме на следующем этапе.

Загляните в галерею примеров, где вы сможете увидеть и насладиться некоторыми очень крутыми проектами, созданными с помощью Dash. Самое приятное, что многие из них с открытым исходным кодом, а это значит, что вы можете многое для себя почерпнуть и вдохновиться на новые идеи. 

Спасибо за прочтение!


В заключение приглашаем на открытое занятие «Работа с Power BI. Построение дашборда. Настройка и взаимодействие визуальных элементов». На уроке загрузим данные в Power BI Desktop из источника, построим небольшой дашборд, посмотрим на назначение и варианты настройки базовых визуальных элементов. Записаться можно по ссылке.

Sept. 6, 2021

Plotly dashboard created purely in Python.

I don’t have to convince you why we need an interactive dashboard. But most people don’t know that they don’t have to buy expensive licenses of Tableau or PowerBI. You don’t have to enroll in a JavaScript course, either.

Dash apps allow you to build interactive dashboards purely in Python. Interestingly, it could reach heights that popular BI platforms can not.

Unlike other tools to create dashboard web applications, you can host Dash apps on your servers and terms. You can use this tool for various use cases, from a key performance indicator dashboard for your employees that changes once a month to a real-time network monitoring dashboard.

I strongly recommend the book, Interactive Dashboards and Data Apps with Plotly and Dash because it gives an in-depth understanding of interactive dashboard design.

Other resources about Dashboards and Data Visualization:
The Big Book of Dashboards
Storytelling with Data


Why Dash? Why not Tableau, Power BI, or some JavaScript library?

BI Platforms such as Tableau and PowerBI do a fantastic job. It allows even non-technical managers to do data exploration themselves. I don’t have complaints about them.

They are excellent tools for performing analysis on read-only datasets. But in a large data science project, you’ll have to perform complex actions. For instance, you must trigger a backend function and start the model retraining.

In such cases, my best solution was to build a web app from scratch. JavaScript data visualization libraries such as HighCharts are excellent tools for this. They have callbacks for almost every possible user action. I use them to send data back to the server and control it better.

Related: How to Make a PDF Text-to-Speech Reader in Python

But this wasn’t a walk in the park. My data science team is exceptional in Python and R but not JavaScript. Not on web frameworks such as Django either. And that’s not enough; to build modern web apps, you need frontend web frameworks such as React.

As we progressed, we realized the harsh truth. Every new technology in our stack inflates the difficulty exponentially.

And we were fortunate to find Dash—a pure Python open-source web dashboard framework. If you’re comparing Plotly dash vs. react, Dash is built using react, so you don’t have to do the heavy lifting for yourself.

Now, this is how I create my own web dashboards in Python. If you’re looking for a lightweight alternative, check out Streamlit.

Read along if you need flexible, custom dashboards entirely in Python. There’s also an amazing extension to this package that lets you create Dash apps inside Jupyter notebooks. See its repository for more Jupiter dashboard examples.

Streamlit vs. Dash vs. Gradio

Both tools are great for building a dashboard web application. But streamlit is more focused on building quick control panels for ML projects. Plotly is excellent for building cool dashboards at ease.

Another excellent alternative to creating a dashboard web application is Gradio. With gradio, you can even create a dashboard in python Jupiter notebook.

If you create your web dashboard app in either Streamlit or Gradio, it could also work on mobile devices. Your Plotly dashboard app may need a bit more optimization for this.

Building your first dashboard in Python (in less than 1 minute.)

Yes, building dashboards in Dash is that simple. Install Pandas and dash with the following command, then start the timer.

pip install dash pandas

Create a file called app.py in your project directory with the content below.

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd

app = dash.Dash()

df = pd.read_csv(
    "https://raw.githubusercontent.com/ThuwarakeshM/geting-started-with-plottly-dash/main/life_expectancy.csv"
)

fig = px.scatter(
    df,
    x="GDP",
    y="Life expectancy",
    size="Population",
    color="continent",
    hover_name="Country",
    log_x=True,
    size_max=60,
)

app.layout = html.Div([dcc.Graph(id="life-exp-vs-gdp", figure=fig)])


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

Showtime! let’s run the dashboard app with the following command:

python app.py

You’ll see it starting a server at port 8050. If you visit http://127.0.0.1:8050 on your browser, you’d see the dashboard that looks like the following:

Interactive dashboard created in Python using Plotly Dash

You’d appreciate the difference if you’ve created a similar app using JavaScript libraries. Dash saves a ton of time by eliminating an incredible amount of boilerplate code. Even popular BI tools have lots of prework to get to this point.

Awesome. That’s quite a thing for inspiring you to build dashboards. But you might have realized that it’s not dazzling yet. In the following sections, we’ll discuss how

  • we can improve the layout;
  • add interactions and callbacks to the widgets like google analytics and;
  • style the app further.

With this, you can create the dazzling dashboard you need. Browse the Plottly Dash gallery for more of such dashboards for inspiration.

Related: 7 Ways to Make Your Python Project Structure More Elegant

Let’s add more widgets to the layout.

Dash follows an HTML-like element hierarchy. You can attach any of Dash’s HTML or Core components to the layout property of the app. The layout property is the root of a Dash app’s element hierarchy.

Core components are a pre-configured set of widgets such as dropdowns and sliders.

Dash’s HTML components cover almost every HTML element available. To create a heading, you can use html.H1 and html.P to create a paragraph. The children attribute allows you to nest one HTML component within another.

app.layout = html.Div(
    [   
        # Dropdown to filter developing/developed country.
        html.Div(
            [
                dcc.Dropdown(
                    id="status-dropdown",
                    options=[{"label": s, "value": s} for s in df.Status.unique()], # Create available options from the dataset
                ),
            ]
        ),
        # Dropdown to filter countries with average schooling years.
        html.Div(
            [
                dcc.Dropdown(
                    id="schooling-dropdown",
                    options=[
                        {"label": y, "value": y}
                        for y in range(
                            int(df.Schooling.min()), int(df.Schooling.max()) + 1
                        )
                    ], # add options from the dataset.
                ),
            ]
        ),
        # Placeholder to render teh chart.
        html.Div(dcc.Graph(id="life-exp-vs-gdp"), className="chart"),

        # Slider to select year.
        dcc.Slider(
            "year-slider",
            min=df.Year.min(), # dynamically select minimum and maximum years from the dataset.
            max=df.Year.max(),
            step=None,
            marks={year: str(year) for year in range(df.Year.min(), df.Year.max() + 1)}, # set markers at one year interval.
            value=df.Year.min(),
        ),
    ],
)

In the above code, we’ve included three core components—two dropdowns and a slider. These controller elements allow us to filter the chart data and create interactivity in the next section.

Adding interactivity with component callbacks.

Dash’s core components have callbacks to control the response for a user action. This feature is remarkable of why Dash apps outshine popular BI platforms.

You can use this call back to control a chart re-rendering or trigger a heavy analysis. Check out my article on performing massive computations to use with Dash apps and Celery.

Here in this post, we use callbacks to filter the chart data.

@app.callback(
    Output("life-exp-vs-gdp", "figure"),
    Input("year-slider", "value"),
    Input("status-dropdown", "value"),
    Input("schooling-dropdown", "value"),
)
def update_figure(selected_year, country_status, schooling):
    filtered_dataset = df[(df.Year == selected_year)]

    if schooling:
        filtered_dataset = filtered_dataset[filtered_dataset.Schooling <= schooling]

    if country_status:
        filtered_dataset = filtered_dataset[filtered_dataset.Status == country_status]

    fig = px.scatter(
        filtered_dataset,
        x="GDP",
        y="Life expectancy",
        size="Population",
        color="continent",
        hover_name="Country",
        log_x=True,
        size_max=60,
    )

    return fig

The callback function is annotated with the @app.callback decorator. The first argument of this decorator is the Output component in the element tree. We need to specify the id of that element and the property we need to change. This property will change to the return value of the callback function.

Then the decorated will accept any number of input arguments. Each will be tied to a core component as we attached the output component. We can specify the element’s id and the property that emits the change value. Usually, this would be ‘value.’

Each input in the decorator should have a respective argument in the callback function’s definition.

Finally, we moved the figure component inside the callback function. Every time we run the callback function, it creates a new figure instance and updates the UI.

Let’s Style your dashboard (in Python; no CSS.)

You can use the inline styling options available in Dash app. But with little CSS, you could have spectacular results.

In-dash, you can style elements in three different ways.

Inline styling

Every Dash py component accepts a style argument. You can pass a dictionary and style any element. This is the most convenient way to style a Dash app.

html.H1("My Dazzling Dashboard", style={"color": "#011833"}),

Local stylesheets (okay, some CSS if you need.)

Alternatively, you can pass a class name attribute to any Dash component and use a separate CSS file to style it. You should place this CSS file inside an asset folder in your project directory. Dash will automatically pick it and apply its styles to the components.

# - app.py
# - assets/
#     |-- style.css

# style.css
# -----------------------------------------
# .title { color: #011833 }

# app.py
html.H1("My Dazzling Dashboard", className='title')

External stylesheets.

You can also use stylesheets from the internet. For instance, dash has this preconfigured stylesheet with convenient utility classes. You can specify the style sheet and use its class names in elements to make them beautiful.

app = dash.Dash(
    __name__, external_stylesheets="https://codepen.io/chriddyp/pen/bWLwgP.css"
)

# Alternative way
app.css.append_css({
    "external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"
})

final project — creating visualizations and dashboards

Here is the complete styled source code of the application. We’ve used a local stylesheet and organized the HTML to support styling. The full code and the local stylesheet are in this GitHub repository.

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

app = dash.Dash(
    __name__,
)

df = pd.read_csv(
    "https://raw.githubusercontent.com/ThuwarakeshM/geting-started-with-plottly-dash/main/life_expectancy.csv"
)

colors = {"background": "#011833", "text": "#7FDBFF"}

app.layout = html.Div(
    [
        html.H1(
            "My Dazzling Dashboard",
        ),
        html.Div(
            [
                html.Div(
                    [
                        html.Label("Developing Status of the Country"),
                        dcc.Dropdown(
                            id="status-dropdown",
                            options=[
                                {"label": s, "value": s} for s in df.Status.unique()
                            ],
                            className="dropdown",
                        ),
                    ]
                ),
                html.Div(
                    [
                        html.Label("Average schooling years grater than"),
                        dcc.Dropdown(
                            id="schooling-dropdown",
                            options=[
                                {"label": y, "value": y}
                                for y in range(
                                    int(df.Schooling.min()), int(df.Schooling.max()) + 1
                                )
                            ],
                            className="dropdown",
                        ),
                    ]
                ),
            ],
            className="row",
        ),
        html.Div(dcc.Graph(id="life-exp-vs-gdp"), className="chart"),
        dcc.Slider(
            "year-slider",
            min=df.Year.min(),
            max=df.Year.max(),
            step=None,
            marks={year: str(year) for year in range(df.Year.min(), df.Year.max() + 1)},
            value=df.Year.min(),
        ),
    ],
    className="container",
)


@app.callback(
    Output("life-exp-vs-gdp", "figure"),
    Input("year-slider", "value"),
    Input("status-dropdown", "value"),
    Input("schooling-dropdown", "value"),
)
def update_figure(selected_year, country_status, schooling):
    filtered_dataset = df[(df.Year == selected_year)]

    if schooling:
        filtered_dataset = filtered_dataset[filtered_dataset.Schooling <= schooling]

    if country_status:
        filtered_dataset = filtered_dataset[filtered_dataset.Status == country_status]

    fig = px.scatter(
        filtered_dataset,
        x="GDP",
        y="Life expectancy",
        size="Population",
        color="continent",
        hover_name="Country",
        log_x=True,
        size_max=60,
    )

    fig.update_layout(
        plot_bgcolor=colors["background"],
        paper_bgcolor=colors["background"],
        font_color=colors["text"],
    )

    return fig


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

Your web app refreshes as you update your code with the above. And it may look like the below—your first version of a dazzling dashboard.

Screencast of a basic styled Plotly Dash app.

What next in your Dash app journey?

Dash is no doubt the best web dashboard framework for Python developers. Check out the Dash Enterprise App Gallery for more Python dash examples.

A vital benefit of these gallery apps is that they are a rich repository of dash layout examples.

If you’d like to take your Dash skills to the next level, check out this popular course on Udemy. More than 42k people benefited from this course, and about 7.8k rated this course 4.7 stars.

It’s a beneficial resource if you’ve questions about adding authorization to the app or cloud deployment.

Final Thoughts

Plotly, Dash apps are an incredible tool for Python developers. Since most data science teams do not specialize in JavaScript, building dashboards with Dash saves much of their time.

We can use Tableau, PowerBI, and similar BI platforms for data exploration and visualization. But Dash apps outshine them as they tightly integrate with the backend code.

In this article, we explored the surface of Dash apps. I trust this would’ve given you the kickstart to build outstanding dashboards without worrying about scary technology stacks.

As a next step, I strongly recommend exploring Dash’s documentation page and its example gallery.

Веб-разработка с Python: Dash (полное руководство)

Рисование с помощью Plotly, внедрение Bootstrap CSS, загрузка и скачивание файлов, изменение ввода после выбора, панели навигации, счетчики и многое другое…

Резюме

Добро пожаловать в это хардкорное руководство по Dash. После этой статьи вы сможете создать и развернуть базовый прототип (минимально жизнеспособный продукт) для любого типа веб-приложения.

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

В этом руководстве я объясню, как создать полноценное веб-приложение Dash, на примере моего приложения для планирования свадеб (ссылка ниже).

Я представлю некоторый полезный код Python, который можно легко применить в других подобных случаях (просто скопировать, вставить, запустить) и пройтись по каждой строке кода с комментариями, чтобы вы могли воспроизвести этот пример (ссылка на полный код ниже).

В частности, я пройду через:

  • Настройка среды
  • Модель данных
  • Подготовить базовую структуру приложения тире (панель навигации, тело, макет)
  • Входные данные (форма, ползунок, руководство, загрузка файла, изменение входных данных после события)
  • Вывод (Plotly, загрузка файла, счетчик при загрузке)
  • Разверните приложение на Heroku

Настраивать

Первым делом я установлю через терминал следующие библиотеки:

## for application
dash==1.20.0
dash-bootstrap-components==0.12.2
## to produce random data
names==0.3.0
## for data processing
numpy==1.19.5
pandas==1.1.5
## for plotting
plotly==4.14.3
## for read and write excel files
openpyxl==3.0.7
xlrd==1.2.0

Чтобы панель управления выглядела красиво, мы будем использовать Bootstrap, фреймворк CSS / JS, который содержит шаблоны дизайна для форм, кнопок, навигации и других компонентов интерфейса . Пакет D ash-Bootstrap-Components позволяет легко интегрировать Bootstrap в наше приложение Dash.

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

Обратите внимание, что последняя версия xlrd (2.0.0) не принимает файлы .xlsx, поэтому используйте 1.2.0 если вы хотите загрузить файлы Excel.

Модель данных

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

import names
import pandas as pd
import numpy as np

'''
Generate random guests list
:parameter
    :param n: num - number of guests and length of dtf
    :param lst_categories: list - ["family", "friends", ...]
    :param n_rules: num - number of restrictions to apply (ex. if 1 
                    then 2 guests can't be sit together)
:return
    dtf with guests
'''
def random_data(n=100, lst_categories=["family","friends",
                "work","university","tennis"], n_rules=0):
    ## basic list
    lst_dics = []
    for i in range(n):
        name = names.get_full_name()
        category = np.random.choice(lst_categories) if 
                   len(lst_categories) > 0 else np.nan
        lst_dics.append({"id":i, "name":name, "category":category, 
                         "avoid":np.nan})
    dtf = pd.DataFrame(lst_dics)
    ## add rules
    if n_rules > 0:
        for i in range(n_rules):
            choices = dtf[dtf["avoid"].isna()]["id"]
            ids = np.random.choice(choices, size=2)
            dtf["avoid"].iloc[ids[0]] = int(ids[1]) if 
              int(ids[1]) != ids[0] else int(ids[1])+1
    return dtf

Эта функция создает таблицу с информацией о гостях.

Я воспользуюсь столбцом «Категория», чтобы отображать гостей разными цветами:

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

Приложение будет распределять места на основе:

  • награда +1, когда два человека, принадлежащих к одной категории, сидят рядом друг с другом
  • штраф -1, когда два человека, которые хотят избежать друг друга, помещаются за один стол.

Эта функция возвращает тот же фрейм данных с новым столбцом для назначенной таблицы:

Структура приложения

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

  • Ввод — раздел приложения, в котором пользователь может вставлять и выбирать параметры и данные, которые будут использоваться серверной частью для возврата желаемого результата (для панели навигации ввод не требуется).
  • Вывод — раздел приложения, в котором пользователь может визуализировать результаты.
  • Обратные вызовы — декоратор, оборачивающий функцию, в которой нужно указать выходы, входы и состояния; последние позволяют передавать дополнительные значения без использования обратных вызовов (обратные вызовы могут выглядеть пугающе, но на самом деле они ваши лучшие друзья).
# setup
import dash
from dash.dependencies import Input, Output, State
import dash_core_components as dcc
import dash_html_components as html
import dash_bootstrap_components as dbc
# App Instance
app = dash.Dash(name="name")
app.title = "name"
########################## Navbar ##########################
# Input
# Output
navbar = dbc.Nav()
# Callbacks
@app.callback()
def function():
    return 0
########################## Body ##########################
# Input
inputs = dbc.FormGroup()
# Output
body = dbc.Row([
        ## input
        dbc.Col(md=3),
        ## output
        dbc.Col(md=9)
])
# Callbacks
@app.callback()
def function():
    return 0
########################## App Layout ##########################
app.layout = dbc.Container(fluid=True, children=[
    html.H1("name", id="nav-pills"),
    navbar,
    html.Br(),html.Br(),html.Br(),
    body
])
########################## Run ##########################
if __name__ == "__main__":
    app.run_server(debug=True)

Начнем со стиля . Замечательный Dash-Bootstrap-Components предлагает огромное разнообразие предопределенных стилей. Вы можете ознакомиться с ними здесь. Выбрав один из них, вы можете вставить его в экземпляр приложения как внешнюю таблицу стилей. Вы даже можете использовать более одного:

theme = dbc.themes.LUX
css = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'
# App Instance
app = dash.Dash(name="name",
                external_stylesheets=[theme, css])

Перейдем к верхней панели навигации. Я добавлю ссылку, всплывающее окно и раскрывающееся меню.

Как видите, панель навигации классная и реагирует на нажатие, с всплывающими окнами и раскрывающимся меню. Выпадающее меню «Ссылки» очень простое, так как для его работы не требуется обратный вызов, а всплывающее меню «О программе» немного сложно.

Навигационная панель содержит 3 навигационных элемента: логотип, кнопку «О программе», раскрывающееся меню. Кнопка «О программе» включает в себя 2 элемента: навигационную ссылку (которая обычно используется для навигации по многостраничному приложению, но в данном случае href = ”/”) и всплывающее окно (зеленый и красный Метки). Эти 2 элемента вызываются в обратном вызове как выходы, входы и состояния, как это, если щелкнуть навигационную ссылку «О программе», тогда всплывающее окно станет активным и появится. Функция python about_popover () ожидает 3 аргумента, потому что обратный вызов имеет один вход и два состояния, и возвращает 2 переменные, поскольку обратный вызов имеет два выхода. Когда приложение запускается и кнопка не нажимается n = 0.

Обратите внимание, что раскрывающееся меню (синяя часть) включает шрифты, импортированные с помощью внешней таблицы стилей (т. Е. className = ”fa fa-linkedin”).

Панель навигации, которую мы только что видели, является одним из элементов окончательного макета вместе с заголовком и основным телом:

Теперь поговорим о слоне в комнате… основном теле. Он состоит из входов (слева) и выходов (справа), которые взаимодействуют друг с другом благодаря обратным вызовам.

Входы

Обычно входные данные объединяются в группу форм и отправляются при нажатии кнопки Форма. Ползунки и ввод вручную — самые распространенные элементы формы.

Вот как можно создать обычный слайдер:

dcc.Slider(id="n-guests", min=10, max=100, step=1, value=50, 
           tooltip={'always_visible':False})

и вот как установить в ползунке только определенные значения:

dcc.Slider(id="n-iter", min=10, max=1000, step=None, 
           marks={10:"10", 100:"100", 500:"500", 1000:"1000"}, 
           value=0),

Это простой ручной ввод:

dbc.Input(id="max-capacity", placeholder="table capacity", 
          type="number", value="10"),

Давайте увеличим сложность и разберемся с ситуацией «Загрузка файла». Я собираюсь дать пользователям возможность загрузить файл Excel, содержащий аналогичный набор данных, который мы сгенерировали случайным образом:

При загрузке файла я хочу, чтобы произошло два события:

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

Как нам этого добиться? Легко, с волшебным обратным вызовом, который изменяет стиль CSS компонентов HTML:

Чтобы использовать загруженный файл, нам нужно проанализировать его и преобразовать в фрейм данных pandas, и мы собираемся использовать для этого эту функцию:

import pandas as pd
import base64
import io
'''
When a file is uploaded it contains "contents", "filename", "date"
:parameter
    :param contents: file
    :param filename: str
:return
    pandas table
'''
def upload_file(contents, filename):
    content_type, content_string = contents.split(',')
    decoded = base64.b64decode(content_string)
    try:
        if 'csv' in filename:
            return pd.read_csv(io.StringIO(decoded.decode('utf-8')))
        elif 'xls' in filename:
            return pd.read_excel(io.BytesIO(decoded))
    except Exception as e:
        print("ERROR:", e)
        return 'There was an error processing this file.'

Прежде чем перейти к выводам, давайте подведем итоги того, что мы видели до сих пор. Вот полный код входов в основном теле:

########################## Body ##########################
# Input
inputs = dbc.FormGroup([
    ## hide these 2 inputs if file is uploaded
    html.Div(id='hide-seek', children=[
        dbc.Label("Number of Guests", html_for="n-guests"), 
        dcc.Slider(id="n-guests", min=10, max=100, step=1, value=50, 
                   tooltip={'always_visible':False}),
        dbc.Label("Number of Rules", html_for="n-rules"), 
        dcc.Slider(id="n-rules", min=0, max=10, step=1, value=3, 
                   tooltip={'always_visible':False})
    ], style={'display':'block'}),
    ## always visible
    dbc.Label("Number of Trials", html_for="n-iter"), 
    dcc.Slider(id="n-iter", min=10, max=1000, step=None, 
               marks={10:"10", 100:"100", 500:"500", 1000:"1000"}, 
               value=0),
    html.Br(),
    dbc.Label("Max Guests per Table", html_for="max-capacity"), 
    dbc.Input(id="max-capacity", placeholder="table capacity", 
              type="number", value="10"),
    ## upload a file
    html.Br(),
    dbc.Label("Or Upload your Excel", html_for="upload-excel"), 
    dcc.Upload(id='upload-excel', children=html.Div([
               'Drag and Drop or ', html.A('Select Files')]),
               style={'width':'100%', 'height':'60px', 
                      'lineHeight':'60px', 'borderWidth':'1px',  
                      'borderStyle':'dashed',
                      'borderRadius':'5px', 'textAlign':'center', 
                      'margin':'10px'} ),
    html.Div(id='excel-name', style={"marginLeft":"20px"}),
    ## run button
    html.Br(),html.Br(),
    dbc.Col(dbc.Button("run", id="run", color="primary"))
])

# Callbacks
@app.callback(
 output=[
  Output(component_id="hide-seek", component_property="style"),
  Output(component_id="excel-name", component_property="children")], 
 inputs=[
  Input(component_id="upload-excel",component_property="filename")])
def upload_event(filename):
    div = "" if filename is None else "Use file "+filename
    return {'display':'block'} if filename is None else 
           {'display':'none'}, div

Выходы

Серверная часть должна выдавать 3 вывода: заголовок, ссылку для загрузки результатов в виде файла Excel и, очевидно, график.

Приступим к сюжету, сделанному с помощью Plotly. По сути, есть два основных модуля этой удивительной графической библиотеки: plotly express и graph_objects. Первый — это графический инструмент высокого уровня, содержащий функции, которые могут создавать целые фигуры сразу (я нахожу это похожим на seaborn), в то время как последний позволяет вам строить фигуру по кирпичику (на самом деле это то, что сюжетно выражает работает под капотом).

Экспресс-график идеально подходит, если вы хотите стилизовать данные на основе значений определенных столбцов, поэтому здесь я собираюсь использовать это, но если вы хотите увидеть примеры графиков, созданных с помощью graph_objects, ознакомьтесь с «эта статья».

Итак … что это?

Это может выглядеть как рисунок, но это правильная геометрическая фигура: это диаграмма рассеяния, цвет на которой основан на категории, к которой принадлежат гости (семья, друзья,…), размер определяется тем, хочет ли гость избегать кого-то. или нет (в основном я выделяю проблемные), а фасетный компонент связан с таблицей, назначенной каждому гостю. Фасетные графики — это фигуры, составленные из нескольких подзаголовков, которые имеют одинаковый набор осей, где каждый подзаголовок показывает подмножество данных.

Прежде всего, мне нужно добавить координаты x и y для графика, используя уравнение круга: (x, y) = (r * cosθ, r * sinθ). Затем я добавляю столбец «размер» на основе столбца «избегать»:

def prepare_data(dtf):
    ## mark the rules
    dtf["avoid"] = dtf["avoid"].apply(lambda x: 
                     dtf[dtf["id"]==x]["name"].iloc[0] if 
                     pd.notnull(x) else "none")
    dtf["size"] = dtf["avoid"].apply(lambda x: 1 if x == "none" 
                     else 3)
    ## create axis
    dtf_out = pd.DataFrame()
    lst_tables = []
    for t in dtf["table"].unique():
        dtf_t = dtf[dtf["table"]==t]
        n = len(dtf_t)
        theta = np.linspace(0, 2*np.pi, n)
        dtf_t["x"] = 1*np.cos(theta)
        dtf_t["y"] = 1*np.sin(theta)
        dtf_out = dtf_out.append(dtf_t)
    return dtf_out.reset_index(drop=True).sort_values("table")

Затем я могу просто использовать команды plotly для создания фигур и указать, какая информация будет отображаться при наведении указателя мыши на точки:

import plotly.express as px
fig = px.scatter(dtf, x="x", y="y", color="category", 
                 hover_name="name", facet_col="table", 
                 facet_col_wrap=3, size="size",                         
                 hover_data={"x":False, "y":False, "category":True, 
                             "avoid":True, "size":False,  
                             "table":False}
              )         
fig.add_shape(type="circle", opacity=0.1, fillcolor="black", 
              col="all", row="all", exclude_empty_subplots=True,                       
              x0=dtf["x"].min(), y0=dtf["y"].min(), 
              x1=dtf["x"].max(), y1=dtf["y"].max()
              )         
fig.update_layout(plot_bgcolor='white', 
                  legend={"bordercolor":"black", 
                          "borderwidth":1, 
                          "orientation":"h"}
              )

Полный код для сюжета (и заголовок):

Теперь, когда график готов, как загрузить результаты в виде файла Excel? Нам просто нужна функция, которая преобразует фрейм данных pandas в файл и передает ссылку для его загрузки в пользовательский интерфейс:

import pandas as pd
import io
import base64
'''
Write excel
:parameter
    :param dtf: pandas table
:return
    link
'''
def download_file(dtf):
    xlsx_io = io.BytesIO()
    writer = pd.ExcelWriter(xlsx_io)
    dtf.to_excel(writer, index=False)
    writer.save()
    xlsx_io.seek(0)
    media_type = 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
    data = base64.b64encode(xlsx_io.read()).decode("utf-8")
    link = f'data:{media_type};base64,{data}'
    return link

На стороне интерфейса мы должны добавить HTML-ссылку для загрузки и проделать обычный трюк с обратным вызовом:

Как вы могли заметить, выходные данные (заголовок, загрузка, сюжет) заключены в Spinner, который воспроизводит этот приятный эффект состояния загрузки при разработке входных данных:

Развертывать

Наконец, мы готовы развернуть это приложение. Вот полный код приложения Dash (с остальной частью репозитория вы можете ознакомиться на GitHub):

Лично мне нравится Heroku за развертывание прототипов . Вам нужно будет добавить requirements.txt и Procfile. Если вам нужна помощь, вы можете найти подробные руководства здесь и здесь.

Вывод

Эта статья представляет собой (почти) полное руководство о том, как создать хорошее веб-приложение с помощью Python Dash. Это приложение довольно простое, поскольку в нем нет базы данных и функции входа в систему (может быть, материал для следующего руководства?). Здесь я просто хотел продемонстрировать, как вы можете легко превратить свои идеи в прототип, чтобы показать миру. А теперь, когда вы знаете, как это работает, вы можете разработать собственное приложение.

Я надеюсь, что вам понравилось! Не стесняйтесь обращаться ко мне с вопросами и отзывами или просто для того, чтобы поделиться своими интересными проектами.

LinkedIn | Инстаграм | Twitter | GitHub

Эта статья является частью серии Веб-разработка с помощью Python, см. Также:

«Создание и развертывание бота Telegram с краткосрочной и долгосрочной памятью
Создайте чат-бота с нуля, который запоминает и напоминает события с помощью Python pub.towardsai. сеть»

Build A Dashboard In Python – Plotly Dash Step-by-Step Tutorial

From my experience here at

STATWORX

, the best way to learn something is by trying it out yourself – with a little help from a friend! In this article, I will focus on giving you a hands-on guide on how to build a dashboard in Python. As framework, we will be using Dash, and the goal is to create a basic dashboard with a dropdown and two reactive graphs:

Developed as an open-source library by Plotly, the Python framework Dash is built on top of Flask, Plotly.js, and React.js. Dash allows the building of interactive web applications in pure Python and is particularly suited for sharing insights gained from data.

For our purposes, a basic understanding of HTML and CSS can be helpful. Nevertheless, I will provide you with external resources and explain every step thoroughly, so you’ll be able to follow the guide.

The source code can be found on

GitHub

.

The project comprises a style sheet called style.css, sample stock data stockdata2.csv and the actual Dash application app.py

If you want your dashboard to look like the one above, please download the file

style.css

from our STATWORX GitHub. That is completely optional and won’t affect the functionalities of your app. Our stylesheet is a customized version of the stylesheet used by the

Dash Uber Rides Demo

. Dash will automatically load any .css-file placed in a folder named assets.

The documentation on external resources in dash can be found

here

.

Feel free to use the same data we did (

stockdata2.csv

), or any pick any data with the following structure:

date

stock

value

change

2007-01-03

MSFT

23.95070

-0.1667

2007-01-03

IBM

80.51796

1.0691

2007-01-03

SBUX

16.14967

0.1134

df = pd.read_csv(‘data/stockdata2.csv’, index_col=0, parse_dates=True)

df.index = pd.to_datetime(df[‘Date’])

Getting Started – How to start a Dash app

After installing Dash (instructions can be found

here

), we are ready to start with the application. The following statements will load the necessary packages dash and dash_html_components. Without any layout defined, the app won’t start. An empty html.Div will suffice to get the app up and running.

import dash_html_components as html

If you have already worked with the

WSGI

web application framework

Flask

, the next step will be very familiar to you, as Dash uses Flask under the hood.

app = dash.Dash(__name__)

if __name__ == ‘__main__’:

app.run_server(debug=True)

How a .css-files changes the layout of an app

Worth to mention is that the nesting of components is done via the children attribute.

app.layout = html.Div(children=[

html.Div(className=‘row’, # Define the row element

html.Div(className=‘four columns div-user-controls’), # Define the left element

html.Div(className=‘eight columns div-for-charts bg-grey’) # Define the right element

The first html.Div() has one child. Another html.Div named row, which will contain all our content. The children of row are four columns div-user-controls and eight columns div-for-charts bg-grey.

The style for these div components come from our style.css.

Now let’s first add some more information to our app, such as a title and a description. For that, we use the Dash Components H2 to render a headline and P to generate html paragraphs.

html.H2(‘Dash — STOCK PRICES’),

html.P(»’Visualising time series with Plotly — Dash»’),

html.P(»’Pick one or more stocks from the dropdown below.»’)

Switch to your terminal and run the app with python app.py.

The basics of an app’s layout

Another nice feature of Flask (and hence Dash) is

hot-reloading

. It makes it possible to update our app on the fly without having to restart the app every time we make a change to our code.

Running our app with debug=True also adds a button to the bottom right of our app, which lets us take a look at error messages, as well a Callback Graph. We will come back to the Callback Graph in the last section of the article when we’re done implementing the functionalities of the app.

Charting in Dash – How to display a Plotly-Figure

With the building blocks for our web app in place, we can now define a plotly-graph. The function dcc.Graph() from dash_core_components uses the same figure argument as the plotly package. Dash translates every aspect of a plotly chart to a corresponding key-value pair, which will be used by the underlying JavaScript library Plotly.js.

In the following section, we will need the express version of plotly.py, as well as the Package Dash Core Components. Both packages are available with the installation of Dash.

import dash_core_components as dcc

import plotly.express as px

Dash Core Components

has a collection of useful and easy-to-use components, which add interactivity and functionalities to your dashboard.

Plotly Express

is the express-version of plotly.py, which simplifies the creation of a plotly-graph, with the drawback of having fewer functionalities.

To draw a plot on the right side of our app, add a dcc.Graph() as a child to the html.Div() named eight columns div-for-charts bg-grey. The component dcc.Graph() is used to render any plotly-powered visualization. In this case, it’s figure will be created by px.line() from the Python package plotly.express. As the express version of Plotly has limited native configurations, we are going to change the layout of our figure with the method update_layout(). Here, we use rgba(0, 0, 0, 0) to set the background transparent. Without updating the default background- and paper color, we would have a big white box in the middle of our app. As dcc.Graph() only renders the figure in the app; we can’t change its appearance once it’s created.

dcc.Graph(id=‘timeseries’,

config={‘displayModeBar’: False},

template=‘plotly_dark’).update_layout(

{‘plot_bgcolor’: ‘rgba(0, 0, 0, 0)’,

‘paper_bgcolor’: ‘rgba(0, 0, 0, 0)’})

After Dash reload the application, you will end up in something like that: A dashboard with a plotted graph:

Another core component is dcc.dropdown(), which is used – you’ve guessed it – to create a dropdown menu. The available options in the dropdown menu are either given as arguments or supplied by a function.
For our dropdown menu, we need a function that returns a list of dictionaries. The list contains dictionaries with two keys,
label and value. These dictionaries provide the available options to the dropdown menu. The value of label is displayed in our app. The value of value will be exposed for other functions to use, and should not be changed.
If you prefer the full name of a company to be displayed instead of the short name, you can do so by changing the value of the key
label to Microsoft. For the sake of simplicity, we will use the same value for the keys label and value.

Add the following function to your script, before defining the app’s layout.

# Creates a list of dictionaries, which have the keys ‘label’ and ‘value’.

def get_options(list_stocks):

dict_list.append({‘label’: i, ‘value’: i})

With a function that returns the names of stocks in our data in key-value pairs, we can now add dcc.Dropdown() from the Dash Core Components to our app. Add a html.Div() as child to the list of children of four columns div-user-controls, with the argument className=div-for-dropdown. This html.Div() has one child, dcc.Dropdown().

We want to be able to select multiple stocks at the same time and a selected default value, so our figure is not empty on startup. Set the argument multi=True and chose a default stock for value.

html.Div(className=‘div-for-dropdown’,

dcc.Dropdown(id=‘stockselector’,

options=get_options(df[‘stock’].unique()),

value=[df[‘stock’].sort_values()[0]],

style={‘backgroundColor’: ‘#1E1E1E’},

className=‘stockselector’)

style={‘color’: ‘#1E1E1E’})

The id and options arguments in dcc.Dropdown() will be important in the next section. Every other argument can be changed. If you want to try out different styles for the dropdown menu, follow the

link

for a list of different dropdown menus.

How to add interactive functionalities to your app

Callbacks add interactivity to your app. They can take inputs, for example, certain stocks selected via a dropdown menu, pass these inputs to a function and pass the return value of the function to another component. We will write a function that returns a figure based on provided stock names. A callback will pass the selected values from the dropdown to the function and return the figure to a dcc.Grapph() in our app.

At this point, the selected values in the dropdown menu do not change the stocks displayed in our graph. For that to happen, we need to implement a callback. The callback will handle the communication between our dropdown menu 'stockselector' and our graph 'timeseries'. We can delete the figure we have previously created, as we won’t need it anymore.

We want two graphs in our app, so we will add another dcc.Graph() with a different id.

  • Remove the figure argument from dcc.Graph(id='timeseries')

  • Add another dcc.Graph() with className='change' as child to the html.Div() named eight columns div-for-charts bg-grey.

dcc.Graph(id=‘timeseries’, config={‘displayModeBar’: False})

dcc.Graph(id=‘change’, config={‘displayModeBar’: False})

Callbacks add interactivity to your app. They can take Inputs from components, for example certain stocks selected via a dropdown menu, pass these inputs to a function and pass the returned values from the function back to components.

In our implementation, a callback will be triggered when a user selects a stock. The callback uses the value of the selected items in the dropdown menu (Input) and passes these values to our functions update_timeseries() and update_change(). The functions will filter the data based on the passed inputs and return a plotly figure from the filtered data. The callback then passes the figure returned from our functions back to the component specified in the output.

A callback is implemented as a decorator for a function. Multiple inputs and outputs are possible, but for now, we will start with a single input and a single output. We need the class dash.dependencies.Input and dash.dependencies.Output.

Add the following line to your import statements.

from dash.dependencies import Input, Output

Input() and Output() take the id of a component (e.g. in dcc.Graph(id='timeseries') the components id is 'timeseries') and the property of a component as arguments.

@app.callback(Output(‘id of output component’, ‘property of output component’),

[Input(‘id of input component’, ‘property of input component’)])

def arbitrary_function(value_of_first_input):

The property of the input component is passed to the function as value_of_first_input.

The functions return value is passed to the property of the output component.

If we want our stockselector to display a time series for one or more specific stocks, we need a function. The value of our input is a list of stocks selected from the dropdown menu stockselector.

The function draws the traces of a plotly-figure based on the stocks which were passed as arguments and returns a figure that can be used by dcc.Graph(). The inputs for our function are given in the order in which they were set in the callback. Names chosen for the function’s arguments do not impact the way values are assigned.

Update the figure time series:

@app.callback(Output(‘timeseries’, ‘figure’),

[Input(‘stockselector’, ‘value’)])

def update_timeseries(selected_dropdown_value):

»’ Draw traces of the feature ‘value’ based one the currently selected stocks »’

# Draw and append traces for each stock

for stock in selected_dropdown_value:

trace.append(go.Scatter(x=df_sub[df_sub[‘stock’] == stock].index,

y=df_sub[df_sub[‘stock’] == stock][‘value’],

textposition=‘bottom center’))

data = [val for sublist in traces for val in sublist]

colorway=[«#5E0DAC», ‘#FF4F00’, ‘#375CB1’, ‘#FF7400’, ‘#FFF400’, ‘#FF0056’],

paper_bgcolor=‘rgba(0, 0, 0, 0)’,

plot_bgcolor=‘rgba(0, 0, 0, 0)’,

title={‘text’: ‘Stock Prices’, ‘font’: {‘color’: ‘white’}, ‘x’: 0.5},

xaxis={‘range’: [df_sub.index.min(), df_sub.index.max()]},

  • A trace will be drawn for each stock. Create an empty list for each trace from the plotly figure.

Within the for-loop, a trace for a plotly figure will be drawn with the function go.Scatter().

  • Iterate over the stocks currently selected in our dropdown menu, draw a trace, and append that trace to our list from step 1.

Plotly figures are dictionaries with the keys data and layout. The value of data is our flattened list with the traces we have drawn. The layout is defined with the plotly class go.Layout().

  • Add the trace to our figure

  • Define the layout of our figure

Now we simply repeat the steps above for our second graph. Just change the data for our y-Axis to change and slightly adjust the layout.

Update the figure change:

@app.callback(Output(‘change’, ‘figure’),

[Input(‘stockselector’, ‘value’)])

def update_change(selected_dropdown_value):

»’ Draw traces of the feature ‘change’ based one the currently selected stocks »’

# Draw and append traces for each stock

for stock in selected_dropdown_value:

trace.append(go.Scatter(x=df_sub[df_sub[‘stock’] == stock].index,

y=df_sub[df_sub[‘stock’] == stock][‘change’],

textposition=‘bottom center’))

data = [val for sublist in traces for val in sublist]

colorway=[«#5E0DAC», ‘#FF4F00’, ‘#375CB1’, ‘#FF7400’, ‘#FFF400’, ‘#FF0056’],

paper_bgcolor=‘rgba(0, 0, 0, 0)’,

plot_bgcolor=‘rgba(0, 0, 0, 0)’,

title={‘text’: ‘Daily Change’, ‘font’: {‘color’: ‘white’}, ‘x’: 0.5},

xaxis={‘showticklabels’: False, ‘range’: [df_sub.index.min(), df_sub.index.max()]},

Run your app again. You are now able to select one or more stocks from the dropdown. For each selected item, a line plot will be generated in the graph. By default, the dropdown menu has search functionalities, which makes the selection out of many available options an easy task.

Visualize Callbacks – Callback Graph

With the callbacks in place and our app completed, let’s take a quick look at our callback graph. If you are running your app with debug=True, a button will appear in the bottom right corner of the app. Here we have access to a callback graph, which is a visual representation of the callbacks which we have implemented in our code. The graph shows that our components timeseries and change display a figure based on the value of the component stockselector.
If your callbacks don’t work how you expect them to, especially when working on larger and more complex apps, this tool will come in handy.

Let’s recap the most important building blocks of Dash. Getting the App up and running requires just a couple lines of code. A basic understanding of HTML and CSS is enough to create a simple Dash dashboard. You don’t have to worry about creating interactive charts, Plotly already does that for you. Making your dashboard reactive is done via Callbacks, which are functions with the users‘ interaction as the input.

If you liked this blog, feel free to contact me via

LinkedIn

or

Email

. I am curious to know what you think and always happy to answer any questions about data, my journey to data science, or the exciting things we do here at

STATWORX

.

Содержание

  1. Краткое руководство по Dash — Python веб-фреймворк для создания дэшбордов. Installation + Dash Layout
  2. Начнем.
  3. Примечание
  4. На заметку
  5. Но есть несколько важных замечаний:
  6. Многоразовые компоненты
  7. Немного о таблицах
  8. Компоненты ядра (Основные компоненты)
  9. Остались вопросы?
  10. Summary
  11. Визуализация данных с помощью Python Dash
  12. Установка Dash и Plotly
  13. Требования по использованию Dash
  14. Создание Dash-приложения
  15. Создание app.layout
  16. Компоненты HTML и CSS в Dash
  17. Основные компоненты Dash
  18. Создание финального интерфейса визуализации данных с помощью Python Dash
  19. Заключение

Краткое руководство по Dash — Python веб-фреймворк для создания дэшбордов. Installation + Dash Layout

Сегодня предлагаю погрузиться в один из удобнейших веб-фреймворков в связке c Python под названием Dash. Появился он не так давно, пару лет назад благодаря разработчикам фреймворка plotly. Сам Dash является связкой Flask, React.Js, HTML и CSS.

Выступление Криса Пармера на PLOTCON 2016

Давайте сразу установим фреймворк. Обновленные версии уточняйте тут.

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

Начнем.

Приложения Dash состоят из двух частей. Первая часть — «layout» описывает то, как выглядит наше приложение. Вторая часть описывает интерактивность приложения, о ней мы поговорим в следующей статье.

Dash предоставляет Python классы для всех визуальных компонентов приложения. Разработчики предоставляют набор компонентов в так называемых dash_core_components и dash_html_components . Но также вы можете построить свой компонент используя JavaScript и React.js.

В dash_core_components содержатся различные динамические формы такие как, например, выпадающие списки, графики и чек-боксы.

В dash_html_components содержатся html конструкции, которыми можно завернуть наши формы. Например Div блоки или теги заголовков H1, H2, и так далее. Разработчики предоставляют нам некую абстракцию от html с помощью словарей Python.

Чтобы начать разбираться, создадим файл app.py , в котором будет содержаться следующее:

И запустим его из текущей директории командой:
$ python app.py

. Running on http://127.0.0.1:8050/ (Press CTRL+C to quit)

Видим, что сервер запустился и готов принимать запросы на порт 8050 (у вас может быть другой порт).

Переходим по адресу http://127.0.0.1:8050/
и видим:

Примечание

На заметку

Dash содержит привычную веб разработчика фичу: hot-reloading . Она активируется в тот момент, когда запускается функция app.run_server(debug=True) . Эта фича обновляет ваш браузер всякий раз, когда вы делаете правки в коде и сохраняете результат. Таким образом нет нужды каждый раз перезапускать сервер.

Как мы помним, Dash содержит компонент для каждого тега HTML. Но также он может принимать все аргументы ключевых слов, как и элементы HTML.

Давайте немного изменим наш код:

Обновляем страницу, и видим:

В этом примере мы изменили стили html.Div и html.H1 с помощью свойства style .

html.H1(‘Hello Dash’, style=<‘textAlign’: ‘center’, ‘color’: ‘#7FDBFF’>) отрендерится в приложении Dash как:

Но есть несколько важных замечаний:

Многоразовые компоненты

Продолжая, представим, что нам нужны некоторые элементы, которые будут меняться, например в зависимости от входных данных пользователя нашего приложения. Для этого в Dash предусмотрены так называемые reusable components . Рассмотрим их на примере таблицы, данные для которой будут загружаться из Pandas dataframe.

Немного о таблицах

Давайте вспомним что из себя представляет таблица в HTML.

HTML таблица определяется тэгом table.

Каждая строка таблица определяется тэгом tr. Хедер таблица определяется тэгом th. A ячейки таблицы заполняются с помощью тэга td.

Получается такая структура:

И выглядит она так:

Firstname Lastname Age
Jill Smith 50
Eve Jackson 94
John Doe 80

Компоненты ядра (Основные компоненты)

Как мы уже сказали ранее, dash_core_components включает в себя высокоуровнвые элементы. Такие, как: выпадающее меню, графики и прочее.

Вы можете ознакомиться с визуальной стороной этих элементов, каждый из которых сопровождается кодом (очень удобно, вселенский респект разрабочикам из Plot.ly) здесь.

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

Давайте рассмотрим следующий код:

Тут мы видим, что мы создали как обычно один общий Div блок, в котором содержатся наши различные компоненты ядра. Выглядит это как-то так:

Остались вопросы?

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

Summary

Ранее нами изученый layout описывает то, как выглядит наше приложение. По сути он содержит древовидную иерархию HTML тэгов и высокоуровневых элементов ядра Dash, которые содержатся в dash_core_components .

В следующей части мы изучим то, как сделать нашу страничку интерактивной. Если вам понравился данный туториал, ставьте плюсик и подписывайтесь на меня.

* Здесь скоро будет ссылка на следующую часть *

Источник

Визуализация данных с помощью Python Dash

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

Если речь идет о данных, значит, это касается и Python. В частности, мы говорим о библиотеке Dash, которая построена на базе одной из самых популярных библиотек для построения графиков — Plotly.

Dash позволяет легко создавать и делиться результатами анализа данных с помощью интерактивных дашбордов, используя только код Python. Нет необходимости изучать HTML, CSS или сложные JavaScript-фреймворки, такие как React.js.

В этом руководстве вы получите представление о том, на что способен Dash, и как интегрировать его в свой рабочий процесс.

Установка Dash и Plotly

Вы можете установить Dash с помощью pip . Также необходимо инсталлировать библиотеку pandas для работы с наборами данных:

Приведенная выше команда также выполняет установку plotly . Plotly известен своими интерактивными графиками, и Plotly и Dash созданы Plotly Software Foundation, поэтому библиотеки довольно хорошо работают вместе.

Требования по использованию Dash

У такого мощного фреймворка, как Dash, есть несколько требований. Во-первых, вы должны знать Plotly Python, поскольку Dash может отображать только интерактивные графики Plotly.

Далее, вам необходимо базовое понимание HTML и CSS. Dash похож на React, но на языке Python. Это шаблонный фреймворк, на котором вы можете создать сайт без JavaScript.

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

Создание Dash-приложения

Давайте создадим наше Dash-приложение. После инсталляции импортируем следующие библиотеки:

dash – это глобальная библиотека, содержащая все основные функции. dash_core_components и dash_html_components – это библиотеки, которые устанавливаются с dash по умолчанию. Они включают специфические для Dash фичи и Python-представление HTML-компонентов (тегов). Подробнее о них позже.

Любое приложение Dash запускается с помощью следующей команды:

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

Сначала мы загрузим встроенный датасет из Plotly и создадим простую диаграмму рассеяния:

Затем мы добавляем это изображение в атрибут layout нашего приложения внутри тега div с небольшими текстами:

Теперь мы создаем HTML-теги с помощью библиотеки dash_html_components (html) , а изображение – используя основные компоненты (dcc) library .

За тегом заголовка H1 следует div , содержащий обычный текст, затем сам график с использованием функции Graph библиотеки dcc . Все это находится внутри атрибута children одного тега DIV.

В конце мы также добавляем команду, которая запускает наше приложение в режиме отладки, то есть изменения вступают в силу по мере внесения поправок в скрипт. Вот полный код на данный момент:

Поместите его в скрипт Python и запустите. В терминале вы получите сообщение о том, что необходимо перейти по этой ссылке: http://127.0.0.1:8050/.

В следующих разделах мы подробно расскажем о том, что здесь произошло.

Создание app.layout

Давайте начнем с атрибута layout . Это единственный атрибут, который содержит все ваши HTML-компоненты и изображения. Вы должны передать ему всю вашу графику и HTML-теги в конечном теге DIV.

В зависимости от размера вашего проекта, данный атрибут может стать довольно большим, поэтому я рекомендую создавать все ваши HTML-теги и фигуры в отдельных переменных, а затем передавать их в layout .

Например, вот как будет выглядеть приведенное выше приложение:

Это гораздо аккуратнее и компактнее, и это одна из тех вещей, о которых вы не узнаете в документации Dash. Там куча вложенного кода вместо того, чтобы сделать вышеописанное.

Компоненты HTML и CSS в Dash

Давайте обсудим, как HTML и CSS работают в Dash. Подбиблиотека dash_html_components содержит наиболее распространенные теги HTML, такие как divs, кнопки, текстовые поля, названия, теги заголовков (H1-6) и т. д.

Они реализованы в коде Python под соответствующими именами как представление их HTML-аналогов. Итак, код, подобный приведенному, ниже:

Будет интерпретироваться вашим браузером следующим образом:

Все HTML-теги этой подбиблиотеки содержат следующие основные аргументы:

id : то же, что и атрибут id HTML-тегов

className : то же самое, что и атрибут class тегов HTML

style : такой же, как атрибут style тегов HTML, но принимает только словарь стилей CSS

children : первый аргумент большинства компонентов HTML

Вот пример div с некоторыми кастомизированными настройками:

Аргумент children уникален — он может принимать числа и строки, но чаще всего вы передаете другие компоненты HTML списком, если это тег-контейнер, например такой как div.

Замечание о стилях CSS: большинство атрибутов стиля CSS используют дефисы для разделения слов. Когда вы передаете их в аргумент style Dash , они должны применять camelCase , например backgroundColor вместо background-color .

Я настоятельно рекомендую вам изучить данные HTML-теги, поскольку это единственное, что сохраняет целостность макета (лейаута) вашего приложения. Вот полный список HTML-тегов, поддерживаемых Dash.

Основные компоненты Dash

Другой важной частью Dash являются его основные компоненты. Библиотека dash_core_components содержит несколько других HTML-тегов, но в нее уже встроено немного CSS и JavaScript.

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

Вот несколько образцов этих компонентов, начиная с выпадающего списка:

Выпадающий список с мультивыбором:

Слайдер с помеченными точками останова:

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

Полный список основных компонентов можно посмотреть здесь.

Создание финального интерфейса визуализации данных с помощью Python Dash

В качестве завершающего примера посмотрите на приведенное ниже приложение:

Мы импортируем датасет Diamonds из Seaborn и создаем три графика: диаграмму рассеяния, гистограмму и скрипичную диаграмму. Мы хотим отобразить график рассеяния и гистограмму рядом друг с другом и поместить скрипичную диаграмму прямо под ними в центре.

Для этого мы создаем два div’а, содержащих график рассеяния и гистограмму, left_figure и right_figure . Затем для простоты эти два div помещаем в еще один div — upper_div .

Мы устанавливаем CSS-стиль flex-box для этого div, который размещает фигуры бок о бок.

Затем мы создаем центральный div, содержащий скрипичную диаграмму, и выравниваем его по центру с помощью flex-box и его атрибута justify-content.

Наконец, мы помещаем все в лейаут внутри последнего DIV и запускаем скрипт. Вот конечный результат:

Заключение

Вот краткое описание шагов по созданию базового Dash-приложения:

Создайте приложение с помощью dash.Dash и дайте ему любое название.

Набросайте лейаут своих графиков в дашборде, прежде чем писать код.

Создайте графики, которые войдут в ваш дашборд

Создайте шаблонный лейаут с помощью HTML-компонентов Dash

Добавьте свои изображеня в соответствующие контейнеры

Наконец, добавьте все HTML-компоненты к атрибуту лейаута

Несмотря на то, что мы рассмотрели многие базовые аспекты, такие как HTML, основные компоненты и лейаут приложения, это лишь поверхностное знакомство с возможностями Dash.

Я показал вам множество примеров интерактивных HTML-компонентов, но не рассказал, как интегрировать их в ваше приложение. Как вы можете обновлять графики на основе вводимых пользователем данных, таких как слайдеры, текст или что-то подобное?

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

Dash посвящает большой раздел в документации только для объяснения коллбеков, поскольку поначалу в них трудно разобраться. Я предлагаю вам обратиться к этой теме на следующем этапе.

Загляните в галерею примеров, где вы сможете увидеть и насладиться некоторыми очень крутыми проектами, созданными с помощью Dash. Самое приятное, что многие из них с открытым исходным кодом, а это значит, что вы можете многое для себя почерпнуть и вдохновиться на новые идеи.

Спасибо за прочтение!

В заключение приглашаем на открытое занятие «Работа с Power BI. Построение дашборда. Настройка и взаимодействие визуальных элементов». На уроке загрузим данные в Power BI Desktop из источника, построим небольшой дашборд, посмотрим на назначение и варианты настройки базовых визуальных элементов. Записаться можно по ссылке.

Источник

Dash — библиотека для языка Python с открытым исходным кодом, предназначенная для создания реактивных веб-приложений. Она была загружена на GitHub два года назад в тестовом режиме. Команда разработчиков Dash решила оставить этот прототип в сети, однако продолжила вести работу над проектом уже вне платформы GitHub. Благодаря обратной связи от банков и лабораторий, а также от команд, работающих с анализом данных, разработчики определили курс развития библиотеки. Сегодня уже представлена первая публичная версия Dash, которая подходит как для корпоративных клиентов, так для клиентов премиум-класса продукции Plotly. Библиотека может быть использована как с Plotly, так и самостоятельно.

В настоящее время Dash можно загрузить, используя диспетчер пакетов Python, с помощью команды pip install dash. Dash распространяется с открытым исходным кодом и под лицензией MIT. На официальном сайте вы сможете ознакомиться с руководством по библиотеке, и на GitHub вы найдёте исходный код.

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

Dash значительно упрощает создание GUI (графических пользовательских интерфейсов) для анализа данных. Вот пример приложения на Dash из 43 строк кода, который связывает выпадающее меню с графиком D3.js. Когда пользователь выбирает значение в выпадающем списке, код динамически экспортирует данные из Google Finance в Pandas DataFrame:

Код Dash является декларативным и реактивным, что упрощает создание сложных приложений, содержащих множество интерактивных элементов. Вот пример с 5 входными данными, 3 — выходными и с перекрёстной фильтрацией. Это приложение было написано на Python, и в нём всего лишь 160 строк кода:

Приложение на Dash с несколькими входными и выходными данным.

Для каждого элемента приложения можно задать собственные параметры размера, расположения, цвета и шрифта. Приложения на Dash создаются и публикуются в Сети, поэтому к ним можно применить всё, на что способен CSS. Ниже иллюстрируется пример тонко настраиваемого интерактивного приложения отчётности на Dash, выполненного в стиле отчёта финансовой организации Goldman Sachs.

Тонко настраиваемое приложение Dash, созданное в стиле отчёта финансовой организации Goldman Sachs.

Вам не нужно писать какой-либо код на JavaScript или HTML, когда ваше приложение на Dash запущено в веб-браузере. Dash предоставляет богатый набор интерактивных веб-компонентов.

import dash_core_components as dcc
dcc.Slider(value=4, min=-10, max=20, step=0.5,
           labels={-5: '-5 Degrees', 0: '0', 10: '10 Degrees'})

Пример простого ползунка на Dash

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

@dash_app.callback(Output('graph-id', 'figure'),
                   [Input('slider-id', 'value')])
def your_data_analysis_function(new_slider_value):
    new_figure = your_compute_figure_function(new_slider_value)
    return new_figure

Когда изменяется входной элемент (например, при выборе элемента в выпадающем списке или при передвижении ползунка), декоратор Dash предоставляет вашему коду Python новое входное значение.

Ваша функция Python может выполнять различные действия с новым входным значением: может фильтровать объект DataFrame библиотеки Pandas, выполнять SQL-запрос, запускать симуляцию, выполнять вычисления или запускать тестирование. Dash рассчитывает, что ваша функция вернёт новое свойство для какого-нибудь элемента пользовательского интерфейса, будь то новый график, новая таблица или новый текст.

В качестве примера ниже представлено приложение на Dash, которое обновляет текстовый элемент при взаимодействии с графиком. Код приложения фильтрует данные в Pandas DataFrame на основе выбранной точки:

Приложение ниже отображает метаинформацию о лекарственных веществах при наведении курсора на точки в графике. Код приложения также добавляет строки в таблицу, когда появляются новые компоненты в выпадающем списке.

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

Архитектура

Flask и React.js

Приложения на Dash — веб-серверы, которые запускают Flask и связывают пакеты JSON через HTTP-запросы. Интерфейс Dash формирует компоненты, используя React.js.

Flask — великолепный фреймворк, который широко используется сообществом разработчиков Python во многих проектах. Основной экземпляр Flask и все его настраиваемые свойства доступны разработчикам приложений на Dash. Продвинутые разработчики могут расширить возможности приложений с помощью богатой коллекции плагинов Flask.

React.js также великолепен, например, мы переписали всю нашу веб-платформу и наш онлайн-редактор диаграмм с помощью React. Но есть кое-что, что действительно радует насчёт React — активный и талантливый состав сообщества разработчиков, который опубликовал тысячи высококачественных компонентов, начиная с выпадающих списков и слайдеров, заканчивая календарями и интерактивными таблицами. И всё это публикуется с открытым исходным кодом!

Dash использует мощь Flask и React, подстраивая их под работу с Python для специалистов по анализу и обработке данных, которые могут не быть экспертами в области веб-разработки.

От React.js к компонентам Python

Компоненты Dash — это классы Python, которые кодируют свойства и значения конкретного компонента React и упорядочиваются как JSON. Dash предоставляет набор инструментов для лёгкой упаковки компонентов React в вид компонентов, которые могут быть использованы в Dash. Этот набор инструментов использует динамическое программирования для автоматического создания классов Python из аннотированного свойства React — propTypes. На выходе классы Python, которые представляют компоненты Dash, являются удобными для пользователя, так как они имеют автоматическую проверку аргументов, строк документации и прочее.

Вот пример динамически сгенерированной проверки ошибочного аргумента:

>>> import dash_core_components as dcc
>>> dcc.Dropdown(valu=3)
Ошибка: неизвестный ключевой аргумент `valu`
Допустимые аргументы: id, className, disabled, multi, options, placeholder, value

Пример динамически создаваемых строк документации:

 >>> help(dcc.Dropdown)
class Dropdown(dash.development.base_component.Component)
 |  Компонент выпадающего списка.
 |  Компонент выпадающего списка служит для выбора одного или более
 |  элементов.
 |  значения и названия элементов выпадающего списка определяются в `options`
 |  свойство и выбранный элемент(ы) определяются свойством `value`.
 |
 |  используйте выпадающий список, только если у вас много вариантов выбора (больше 5), или
 | когда вы ограничены пространством. В противном случае вы можете использовать переключатели или чекбоксы,
 |  Которые покажут сразу все элементы пользователю.
 |
 |  Аргументы ключевых слов:
 |  - id (строка; необязательный)
 |  - className (строка; необязательный)
 |  - disabled (логический тип; необязательный): если true, выбор блокируется
 |  - multi (логический тип; необязательный): если true, пользователь может выбрать несколько значений
 |  - options (список; необязательный)
 |  - placeholder (строка; необязательный): серый текст по умолчанию, если ничего не выбрано
 |  - value (строка | список; необязательный): значение поля ввода. Если `multi` false (по умолчанию),
 |  то value — строка, соответствующая своим значениям,
 |  указанным в свойстве `options`. Если `multi` — true, то
 |  можно выбрать сразу несколько значений, а `value` — 
 |  массив элементов со значениями, соответствующими в свойстве 
 |  `options`.
 |
 |  Доступные события: 'change

Полный набор HTML-тегов (наподобие div, img, table) также обрабатывается с помощью React, а их классы Python доступны через библиотеку dash_html_component. Основной набор интерактивных компонентов, таких как Dropdown, Graph, Slider, будет поддерживаться командой Dash через dash_core_components. Обе библиотеки используют стандартный набор инструментальных средств React-to-Dash с открытым исходным кодом, который вы могли бы использовать при необходимости написания своей собственной библиотеки компонентов.

Ваше приложение автоматически не привязывается к библиотеке компонентов Dash. Библиотека компонентов импортируется отдельно от основной библиотеки Dash. С помощью набора инструментальных средств React-to-Dash можно легко записать или перенести компонент React.js в класс Python, который можно использовать в приложении Dash. На официальном сайте вы найдёте руководство по созданию собственных компонентов или можете попросить команду разработчиков Dash написать их для вас.

Многопользовательские приложения

Свойства приложения на Dash хранятся в интерфейсе (в браузере). Это позволяет использовать приложения, написанные с использованием Dash, в многопользовательском режиме: может быть открыто несколько независимых друг от друга сессий, в которых действия одних пользователей не будут влиять на данные других пользователей. Код приложения на Dash является функциональным: он может считывать значения из глобальных свойств Python, но не может вносить в них изменения. Этот функциональный подход можно легко обосновать и протестировать — это просто входные и выходные данные без каких-либо побочных эффектов или свойств.

CSS и стили

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

Визуализация данных

Библиотека Dash поставляется с компонентом Graph, который отвечает за отображение диаграмм с помощью Plotly.js. Библиотека Plotly.js отлично подходит к Dash (отличное дополнение), так как она декларативна и имеет открытый исходный код. Кроме того, она поддерживает полный спектр научных, финансовых и деловых диаграмм. Она создана на основе D3.js (для диаграмм типографического качества и экспорта векторных изображений) и WebGL (для высокопроизводительной визуализации).

В библиотеке Dash элемент Graph использует тот же синтаксис, что и библиотека Plotly.py с открытым исходным кодом, что даёт вам возможность легко переключаться между ними. Компонент Graph подключается к системе событий Plotly.js, позволяя авторам писать приложения, которые реагируют на наведение курсора, щелчки и выбор определённых точек на графиках Plotly.

Репозитории с открытым исходным кодом

  • бэкенд библиотеки Dash;
  • фронтенд библиотеки Dash;
  • библиотека основных компонентов Dash;
  • библиотека HTML-компонентов Dash;
  • набор инструментальных средств React-to-Dash;
  • документация и руководство по Dash;
  • Plotly.js —JavaScript- библиотека, используемая Dash.

Прототипирование

Dash — это новая библиотека в среде Python, однако концепции и идеи, на которых строится Dash, существуют в течение десятилетий на разных языках и в разных приложениях.

Если вы разбираетесь в Excel, значит, вам будет проще разобраться и в Dash. Ведь они оба используют «реактивную» модель программирования. В Excel ячейки с выходными данными обновляются автоматически при изменении параметров ячеек с входными данными. Любая ячейка может быть входной или выходной или и тем, и другим. В ячейках с входными данными нет информации о том, какие ячейки с выходными данными зависят от них, что упрощает добавление новых ячеек с выходными данными или позволяет связать несколько ячеек. Вот пример Excel-приложения:

Можно провести аналогию для Dash. Вместо ячеек у нас есть богатый спектр веб-компонентов, таких как ползунки, поля ввода, выпадающие списки и графики. Вместо написания сценария Excel или VBA мы пишем код Python. Ниже представлено то же самое приложение, но в этот раз оно написано на Dash:

app.layout = html.Div([
    html.Label('Hours per Day'),
    dcc.Slider(id='hours', value=5, min=0, max=24, step=1),
    html.Label('Rate'),
    dcc.Input(id='rate', value=2, type='number'),
    html.Label('Amount per Day'),
    html.Div(id='amount'),
    html.Label('Amount per Week'),
    html.Div(id='amount-per-week')
])
@app.callback(Output('amount', 'children'),
              [Input('hours', 'value'), Input('rate', 'value')])
def compute_amount(hours, rate):
    return float(hours) * float(rate)
@app.callback(Output('amount-per-week', 'children'),
              [Input('amount', 'children')])
def compute_amount(amount):
    return float(amount) * 7

Некоторым разработчикам нравится этот пример, потому что Excel по-прежнему занимает доминирующее положение даже в технических вычислениях и в финансовой математике. Я не думаю, что доминирующее положение Excel — это технический вопрос. В конце концов, есть легионы программистов, которые изучили нюансы Excel, VBA и даже SQL.

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

Тем не менее, моделирование в Excel имеет известные ограничения: эти таблицы часто становятся слишком большими или уязвимыми, чтобы переводить их на производственный уровень, проводить экспертную оценку или тестировать и поддерживать. Вам ведь знаком случай со знаменитой опечаткой в 2013 году?

Надеемся, что Dash сделает использование Python в проектах по обработке данных проще. Благодаря одним и тем же функциональным и реактивным принципам, можно так же легко написать приложение на Dash, как написать аналитическую таблицу. Это, безусловно, более мощный и презентабельный инструмент.

Фреймворк Shiny

Если вы программируете на R, вам повезло. Shiny — это реактивный фреймворк для создания веб-приложений на чистом R, и это отлично! Вы даже можете создавать интерактивные графики с библиотекой Shiny или Plotly для R. Dash и Shiny похожи, но Dash не стремится быть копией Shiny, так как философии Python и R достаточно различаются, что приводит к необходимости использования разного синтаксиса.

Интерактивное веб-приложение, созданное с помощью Shiny на языке R.

Структурирование данных с MATLAB

Если вы программируете на MATLAB, то вам, возможно, знакома GUIDE — библиотека пользовательского интерфейса для MATLAB. Компания Mathworks была одной из новаторов в области технических вычислений. GUIDE была написана в далёком 2004 году.

Приложение, созданное с помощью библиотеки GUIDE на MATLAB.

Если ваши данные структурированы в базе данных, вы могли бы использовать Tableau или любой другой BI-инструмент. Tableau — восхитительный инструмент. Компания установила новый вектор развития в своей отрасли, согласно которому, у конечного пользователя должна быть автономия, чтобы он мог иметь возможность исследовать данные внутри своей организации. Компания также помогла сделать популярнее концепции детализации данных и перекрёстной фильтрации.

Перекрёстная фильтрация в Tableau.

Dash также служит дополнением к BI-инструментам, наподобие вышеупомянутых. Они отлично подходят для структурирования данных. Но когда дело доходит до преобразования данных и аналитики, превзойти размах и гибкость языков программирования и сообществ, вроде Python, становится труднее. Dash абстрагируется от множества сложностей в создании пользовательских интерфейсов, позволяя вам сделать это красиво для вашей аналитической базы данных.

Виджеты Jupyter

Наконец, пришло время рассказать о виджетах Jupyter. Они обеспечивают действительно приятный фреймворк внутри интерфейса Notebook. Вы можете добавлять ползунки к вашим графикам в Jupyter Notebook.

Виджеты в Dash похожи на виджеты Jupyter. В Jupyter Notebooks есть возможность добавлять виджеты непосредственно рядом с кодом. В Dash элементы управления хранятся отдельно от вашего кода. Dash больше нацелена на приложения для распространения, чем на распространяемый код и документацию. Вы всегда можете смешивать и сопоставлять инструменты, создавая свои приложения на Dash в среде Jupyter Notebook.

Команде разработчиков Dash также очень нравится проект nteract, который действительно снижает порог вхождения в Python и Jupyter Notebook, позволяя упаковать Jupyter Notebook в виде настольного приложения.

Лицензирование и бизнес-модель с открытым исходным кодом

Стартап поддерживает библиотеки с открытым исходным кодом для Python, R и MATLAB, которые взаимодействуют с plotly.js. Компания также поддерживает веб-приложение для создания диаграмм и подключения их к базам данных (стыковочные библиотеки также распространяются с открытым исходным кодом).

Если вы используете локальную версию с открытым исходным кодом, в таком случае ограничений нет. Вы можете управлять развёртыванием Dash-приложений самостоятельно через платформы вроде Heroku или Digital Ocean.

Если вы ищите вдохновение для создания своих пользовательских интерфейсов в области технических вычислений, рекомендуем прочитать статью Брета Виктора

Вам также может понравиться проект Explorable Explanations, который специализируется на интерактивном обучении.

Перевод статьи «Create Reactive Web Apps in pure Python»

In this tutorial, you’ll learn how to create Python interactive dashboards using plotly Dash, with an example.

Web-based dashboards are an efficient way to display and share information with others. But it often involves a complicated process that only expert web developers can achieve. As Python programmers in data science, how can we build an interactive web application with data visualizations?

Plotly Dash is the go-to library. It empowers us to build beautiful looking, interactive, and easy to share dashboards, all in Python.

Following this Python Dash tutorial, you’ll learn:

  • What is Dash
  • How to build the Dash app layout with data visualization
  • How to add interactive features (callbacks)
  • How to run and display the dashboard

So if you want to build your first interactive dashboard with Python Dash, this tutorial will walk you through an example step-by-step.

Let’s get started!

Editor’s Note: This tutorial is updated in April 2022 to include the new features in Dash 2.0.

Further learning: to learn more details and depth about Dash, please take our video course: Python Interactive Dashboards with Plotly Dash. It includes step-by-step explanations, more advanced functions, all with real-world dataset examples.


To follow this Python interactive dashboard in Dash tutorial, you need to know Python, including basic knowledge of pandas. If you need help, please check out the below resources:

  • Python basics: FREE Python crash course
  • Python pandas: Python for Data Analysis with projects course. This course teaches pandas, which is necessary to transform the dataset into a dashboard, and much more!

Table Of Contents

  1. What is Dash?
  2. Step #1: Exploring the dataset
  3. Step #2: Setting up the Python environment
  4. Step #3: Preparing to build the Dash app
  5. Step #4: Building the layout of the dashboard
  6. Step #5: Adding interactivity to the dashboard
  7. Step #6: Running the dashboard

What is Dash?

Dash is a free Python library built by the same company that created the plotly graphing library. With Dash, you can develop web-based, customizable, interactive dashboards, all in Python, without writing HTML or JavaScript.

Each Dash app has two main parts:

  • layout: determines what the Dash app looks like
  • callback functions: the function that connects the Dash components and defines their interactive features

We’ll build both parts in this tutorial. Now let’s go through our example to make an interactive data visualization using Dash.

Step #1: Exploring the dataset

Before building the Dash app, we need to explore the dataset. We recommend doing this in JupyterLab/Notebook. Since it has an interactive interface, we can easily code and examine the outputs.

First, we’ll import two libraries (please install them if you haven’t):

  • pandas: for loading and manipulating datasets
  • plotly.express: for generating data visualizations
    Dash is built on top of plotly, so it’s easy to put plotly figures into Dash apps. This is why we are using plotly, instead of other Python data visualization libraries

In this tutorial, we’ll use the Avocado Prices dataset to build our example dashboard. So let’s load it and take a look at its summary.

As you can see, the dataset contains information about avocados.

<class 'pandas.core.frame.DataFrame'>
RangeIndex: 30021 entries, 0 to 30020
Data columns (total 13 columns):
 #   Column         Non-Null Count  Dtype  
---  ------         --------------  -----  
 0   date           30021 non-null  object 
 1   average_price  30021 non-null  float64
 2   total_volume   30021 non-null  float64
 3   4046           30021 non-null  float64
 4   4225           30021 non-null  float64
 5   4770           30021 non-null  float64
 6   total_bags     30021 non-null  float64
 7   small_bags     30021 non-null  float64
 8   large_bags     30021 non-null  float64
 9   xlarge_bags    30021 non-null  float64
 10  type           30021 non-null  object 
 11  year           30021 non-null  int64  
 12  geography      30021 non-null  object 
dtypes: float64(9), int64(1), object(3)
memory usage: 3.0+ MB

Now suppose we want to present the average prices of different types of avocados for various geographies across time, i.e., we want to focus on presenting the information of the columns date, average_price, type, and geography.

Let’s explore these columns more. What are the different type and geography of avocados? Let’s take a look at the categories using the value_counts method. This will show us the unique categories for these variables.

From the results below, you can see that there are two categories of type, and many different categories for geography.

conventional    15012
organic         15009
Name: type, dtype: int64
Phoenix/Tucson          556
Northeast               556
Las Vegas               556
Sacramento              556
Tampa                   556
Spokane                 556
Southeast               556
New York                556
Raleigh/Greensboro      556
Syracuse                556
Plains                  556
California              556
Orlando                 556
Albany                  556
Boise                   556
Boston                  556
Houston                 556
West                    556
Portland                556
Harrisburg/Scranton     556
Cincinnati/Dayton       556
Miami/Ft. Lauderdale    556
Dallas/Ft. Worth        556
Hartford/Springfield    556
Great Lakes             556
Louisville              556
Philadelphia            556
Pittsburgh              556
Baltimore/Washington    556
Roanoke                 556
Jacksonville            556
Midsouth                556
Chicago                 556
San Francisco           556
South Central           556
San Diego               556
Detroit                 556
Grand Rapids            556
Nashville               556
Charlotte               556
Seattle                 556
Los Angeles             556
Northern New England    556
Indianapolis            556
Buffalo/Rochester       556
Total U.S.              556
Richmond/Norfolk        556
New Orleans/Mobile      556
Denver                  556
St. Louis               556
Atlanta                 556
South Carolina          556
Columbus                556
West Tex/New Mexico     553
Name: geography, dtype: int64

Since there are only two avocados types, we can plot their average_price time series on the same line chart. Let’s try creating such a figure when geography is ‘Los Angeles’.

Further Learning: If you are not familiar with plotly, please look at our tutorial, Plotly Python Tutorial: How to create interactive graphs.

python interactive dashboard dash tutorial plotly figure

Plotly Express chart

This is a nice chart, but it’s only for one geography of ‘Los Angeles’.

How can we make it easy for users to explore this information from different geography?

If we have a dropdown with geography options, the users would be able to choose among them. Then according to the geography selected by the users, we can display the above line plot to them for that specific geography.

This is something we can do easily with Dash!

It’s time to use Dash.

Step #2: Setting up the Python environment

After exploring the dataset in Jupyter Notebook, we recommend using one of the Python editors to implement Dash apps. This is because when working on Dash apps, we want to focus on building and running the dashboards as a whole script. So it’s easier to test in Python editors such as PyCharm.

We’re using the PyCharm Editor – Community Edition. It’s free and has many useful features for writing Python code. However, if you still prefer Jupyter Notebook, you can try out the library jupyter-dash, which will not be covered in this tutorial.

It’s also necessary to use the pip install dash command in your terminal to install Dash before using it.

Step #3: Preparing to build the Dash app

We can head over to the Python editor such as PyCharm to start writing the Dash app.

The code snippets below need to be combined and run as a single Python script. We are breaking them down into pieces so that it’s easier to explain. You can either type them into your Python file or copy and paste the complete version, which will be provided in the last step of this tutorial.

First, we need to import the libraries. The necessary ones for our dashboard are:

  • dash: the Dash library, which includes:
    • Dash: class Dash
    • html (Dash HTML Components module): for building the layout, which contains components for every HTML tag, such as the H1 heading
    • dcc (Dash Core Components module): for building the layout, which contains various higher-level components such as dropdown and graph
    • Input, Output: for defining callback functions
  • pandas: loading and manipulating the data
  • plotly.express: creating figures

Then we can load the dataset as a pandas DataFrame, which is the same as earlier. Please make sure you’ve saved this Python script and the dataset avocado-updated-2020.csv in the same directory to avoid setting the path in the read_csv function.

We’ll also create a Dash app object called app. This app is what we’ll be focusing on for the rest of the tutorial.

Step #4: Building the layout of the dashboard

The app-building process always starts from the layout. So first, we need to design the look of the dashboard.

The layout has the structure of a tree of components. And we use the keyword layout of the app to specify its layout. Then, using the two modules: html and dcc, we can display three components on our dashboard, from top to down:

  • an H1 heading (html.H1) as the dashboard’s title. We specify its children property to be the text ‘Avocado Prices Dashboard’
  • a dropdown menu (geo_dropdown, which is a dcc.Dropdown) based on the geography
    We’ve built it as a variable outside and then referenced it within the layout:
    options: this property specifies the options of unique geographies the dropdown has
    value: this property is the selected geography when we first launch the app. We made it as ‘New York’
  • a graph (dcc.Graph) with id ‘price-graph’

Below is the code to set up the layout.

As you might have noticed, we are using an html.Div component to hold our three Dash components. The html.Div is a container component, which is always used when we have multiple Dash components in the layout. We put the other Dash components as a list inside its children property.

After setting up the dashboard’s look, it’s time to add a callback function to make it interactive.

Step #5: Adding interactivity to the dashboard

The callback functions are Python functions. They get automatically called by Dash whenever their inputs change. As a result, the functions run and update their outputs.

The two main sections of the callback function are:

  • decorator, which starts with @app.callback
  • function itself, which begins with def

Below is the code of our callback function to make the plotly figure dependent on the dropdown.

Within the decorator @app.callback, we specify the Output and the Input objects of the callback function. They are both the properties of Dash components.

In our example, the output is the figure property of the Dash component with id = ‘price-graph’, which is the dcc.Graph component set in the layout. While the input is the value property of the Dash component with the variable name geo_dropdown, which is the dcc.Dropdown component set in the layout. So you’ve seen two ways of specifying components in the callback function:

  • pass the ID to component_id
  • pass the variable name directly to component_id, in which case Dash autogenerates IDs for the component

After specifying them, we use them within the function below. Within the parenthesis after the def update_graph, we name the input as selected_geography. This corresponds to the Input(component_id=geo_dropdown, component_property='value'). Then within the body of the function, we ask the function to:

  • generate a filtered dataset filtered_avocado based on selected_geography
  • create a plotly line figure called line_fig based on this filtered dataset

The function returns this line_fig as the output, which corresponds to Output(component_id='price-graph', component_property='figure').

Here is an example. When the user selects ‘Los Angeles’ in the dropdown component, its value property will become ‘Los Angeles’, which means the input of the function selected_geography='Los Angeles'. This change will trigger the callback function, and update the output, as the line figure is only for Los Angeles.

That’s all the work needed for the callback function!

We are ready to run the dashboard.

Step #6: Running the dashboard

By default, the Dash app runs on our local computers. To complete the script, we need to add code to run the server. We can add these two lines of code after the callback function.

And that’s it!

As mentioned earlier, we need to run all the code as a whole script. So if you haven’t, you can copy the complete script below and save it into your Python editor:

So we can name this Python script avocado_example, and save it under the same directory as the dataset avocado-updated-2020.csv. Then we can go to the terminal to run it by typing in the command python avocado_example.py.

After running successfully, you should see the below messages in the terminal window.

Dash is running on http://127.0.0.1:8050/

 * Serving Flask app "avocado_example" (lazy loading)
 * Environment: production
   WARNING: This is a development server. Do not use it in a production deployment.
   Use a production WSGI server instead.
 * Debug mode: on

Remember that Dash creates web applications? So this URL http://127.0.0.1:8050/ is the default address to access the app. You can go to it and see your first Python interactive dashboard opening in the browser!

This is what it should look like:

dash interactive python dashboard example plotly graph tutorial

Python Dash interactive dashboard example

If you haven’t got the chance to run your app, look here. We have deployed this app on Heroku so that you can interact with it as a user. Try to select different geographies within the dropdown and see the updated graph.


In this tutorial, you’ve successfully created your first Python interactive dashboard with plotly Dash!

Again, to learn about how to:

  • set up more Dash components such as range slider, radio items, datatable
  • customize the look of the dashboards
  • create a grid layout dashboard
  • more dynamic interactive features

Please take our video-format course: Python Interactive Dashboards with Plotly Dash. You’ll also get an overview of HTML and CSS within the course to better understand Dash.

Leave a comment for any questions you may have or anything else.

Понравилась статья? Поделить с друзьями:
  • Dashboard в excel скачать пример
  • Dashboard в excel как создать
  • Dashboard view in excel
  • Dashboard tool for excel
  • Dashboard reporting with excel