跳至主要内容

Dash 新手入门

学习如何使用 Dash 在 Python 中构建仪表板。
· 12分钟 阅读

使用 AI 探索

探索 DataCamp 的 Python 课程库

Dash 是用于构建 Web 应用程序的 Python 框架。它构建于 Flask、Plotly.js、React 和 React Js 之上。它使您能够使用纯 Python 构建仪表板。Dash 是开源的,应用在 Web 浏览器中运行。在本教程中,我们将介绍 Dash 的基础知识,并假设读者已经具备 Plotly 的使用经验。

安装 Dash

要开始使用 Dash,我们需要安装几个软件包。

  1. Dash 核心后端。
  2. Dash 前端
  3. Dash HTML 组件
  4. Dash 核心组件
  5. Plotly
pip install dash==0.21.1  
pip install dash-renderer==0.13.0  
pip install dash-html-components==0.11.0
pip install dash-core-components==0.23.0  
pip install plotly --upgrade

Dash 应用布局

一个 Dash 应用通常由两部分组成。第一部分是布局,描述应用的外观;第二部分描述应用的交互性。Dash 提供了 HTML 类,使我们能够用 Python 生成 HTML 内容。要使用这些类,我们需要导入 dash_core_components 和 dash_html_components。您也可以使用 Javascript 和 React Js 创建自定义组件。

首先,我们将使用自己喜欢的文本编辑器创建一个名为 app.py 的文件,然后导入这些包。

import dash
import dash_core_components as dcc
import dash_html_components as html
 

与 Flask 类似,我们通过调用 dash 的 Dash 类来初始化 Dash。完成后,我们就可以为应用创建布局。我们使用 dash_html_components 中的 Div 类来创建一个 HTML Div。然后使用 HTML 组件生成 H1、H2 等 HTML 元素。dash_html_components 包含所有 HTML 标签。要在布局中创建图表,我们使用来自 dash_core_components 的 Graph 类。Graph 使用 plotly.js 渲染交互式数据可视化。Graph 类需要一个包含要绘制的 data 和 layout 细节的 figure 对象。Dash 还允许您进行样式设置,例如更改背景色和文本颜色。您可以使用 style 属性并传入包含特定颜色的对象来更改背景。在我们的示例中,我们定义了一个包含背景色和文本颜色的字典。同样,我们可以使用 plot_bgcolor 属性更改布局背景。

在 HTML 中,style 属性用分号指定,但在 Dash 中传入的是字典。字典中的键使用驼峰式命名,例如 text-align 写作 textAlign。在 Dash 中不使用 HTML 的 class,而是使用 className。

 app = dash.Dash()
colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}
app.layout = html.Div(style={'backgroundColor': colors['background']}, children=[
    html.H1(
        children='Hello Dash',
        style={
            'textAlign': 'center',
            'color': colors['text']
        }
    ),
    html.Div(children='Dash: A web application framework for Python.', style={
        'textAlign': 'center',
        'color': colors['text']
    }),
    dcc.Graph(
        id='Graph1',
        figure={
            'data': [
                {'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': 'SF'},
                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': u'Montréal'},
            ],
            'layout': {
                'plot_bgcolor': colors['background'],
                'paper_bgcolor': colors['background'],
                'font': {
                    'color': colors['text']
                }
            }
        }
    )
])
 

要查看我们的可视化结果,我们需要像在 Flask 中那样运行 Web 服务器。请记住 Dash 构建于 Flask 之上。我们还将 debug 设置为 true,以确保每次修改时不必手动刷新服务器。

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

接下来,打开终端并输入以下代码启动服务器:python app.py

这将在 http://127.0.0.1:8050/ 启动一个新的 Web 服务器。前往该地址查看您新创建的仪表板。

柱状图

生成散点图

要绘制散点图,我们和之前一样导入常用的 dash 组件。同时需要导入 Plotly 的 graph_objs 来绘制散点图。如前所述,我们使用 Dash 的 Div 类和 Graph 组件来完成。Graph 组件接收一个包含数据和布局描述的 figure 对象。我们使用 graph_objs 的 scatter 属性来绘制散点图。为确保绘制的是散点图,我们传入 mode 属性并将其设置为 markers,否则图中将显示为折线。

 import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import plotly.graph_objs as go

app = dash.Dash()

df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/' +
    '5d1ea79569ed194d432e56108a04d188/raw/' +
    'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+
    'gdp-life-exp-2007.csv')


app.layout = html.Div([
    dcc.Graph(
        id='life-exp-vs-gdp',
        figure={
            'data': [
                go.Scatter(
                    x=df[df['continent'] == i]['gdp per capita'],
                    y=df[df['continent'] == i]['life expectancy'],
                    text=df[df['continent'] == i]['country'],
                    mode='markers',
                    opacity=0.8,
                    marker={
                        'size': 15,
                        'line': {'width': 0.5, 'color': 'white'}
                    },
                    name=i
                ) for i in df.continent.unique()
            ],
            'layout': go.Layout(
                xaxis={'type': 'log', 'title': 'GDP Per Capita'},
                yaxis={'title': 'Life Expectancy'},
                margin={'l': 40, 'b': 40, 't': 10, 'r': 10},
                legend={'x': 0, 'y': 1},
                hovermode='closest'
            )
        }
    )
])

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

各洲 x 人均 GDP 散点图

Markdown

有时您可能需要在仪表板中包含大量文本。您可以像下面这样使用 dash_core_components 的 Mardown 属性实现。

 import dash
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

markdown_text = '''
### Dash and Markdown
A lot of text
'''

app.layout = html.Div([
    dcc.Markdown(children=markdown_text)
])

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

核心组件

接下来,让我们看看使用 Dash 时会遇到的一些 dash_core_components。您可以按如下所示生成一个下拉菜单。通过调用 dash_core_components 下的 Dropdown 并传入由字典组成的列表作为 options 即可。您可以使用 values 属性并传入默认选项来设置默认值。

  dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    )

生成多选下拉菜单与上述方式类似。唯一的变化是将 multi 属性设置为 true(默认是 False)。然后通过指定 values 属性来设置默认被多选的选项。

    html.Label('Multi-Select Dropdown'),
    dcc.Dropdown(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value=['MTL', 'SF'],
        multi=True
    )

可以使用 RadioItems 属性生成单选按钮。然后以字典列表的形式传入 options。您也可以通过指定 values 属性来设置默认值。

 html.Label('Radio Items'),
    dcc.RadioItems(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        value='MTL'
    )

要生成复选框,请在 dash_core_components 下调用 Checklist 属性。options 和默认值的传入方式与上面相同。

  html.Label('Checkboxes'),
    dcc.Checklist(
        options=[
            {'label': 'New York City', 'value': 'NYC'},
            {'label': u'Montréal', 'value': 'MTL'},
            {'label': 'San Francisco', 'value': 'SF'}
        ],
        values=['MTL', 'SF']
    )

您的应用很可能需要文本输入。要生成它们,您将使用 Input 属性。借助 Html 的 Label 标签,您可以为输入框创建标签。使用 values 属性可以在字段中指定一些文本;要指定类型,请使用 type 并指明是文本、数字等。

 html.Label('Text Box'),
    dcc.Input(value='MTL', type='text')

多选下拉菜单

调用帮助

由于 Dash 组件是声明式的,对其中任一组件调用帮助命令都会生成该组件的帮助信息。

help(dcc.Input)

交互性

现在让我们介绍如何让 Dash 应用实现交互。为此,我们需要从 dash.dependencies 导入 Input 和 Output。不要将它们与 HTML Input 混淆,因为两者不同。HTML Input 是从 dash core components 导入的。下面我们创建一个文本输入,并将其绑定到一个回调,这样每当您在该输入框中键入内容时,就会实时更新 my-div。为实现这一点,Dash 提供了一个装饰器 @app,可以将回调函数绑定到 my-div 和 HTML 输入框。请注意,我们在定义 update_output_div 函数之前使用了装饰器。

 import dash
import dash_core_components as dcc
import dash_html_components as html
from dash.dependencies import Input, Output

app = dash.Dash()

app.layout = html.Div([
    dcc.Input(id='my-id', value='Dash App', type='text'),
    html.Div(id='my-div')
])


@app.callback(
    Output(component_id='my-div', component_property='children'),
    [Input(component_id='my-id', component_property='value')]
)
def update_output_div(input_value):
    return 'You\'ve entered "{}"'.format(input_value)


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

身份验证

Dash 通过一个名为 dash-auth 的独立包提供身份验证。它提供两种身份验证模式:HTTP 基本认证和 Plotly OAuth。在基本认证中,您在应用中硬编码一组用户名和密码。此方法存在一些问题,例如用户无法注销应用、无法创建账户或更改密码,而且您需要在代码中安全存储用户名和密码。Plotly OAuth 则通过您的在线 Plotly 帐户进行身份验证,但它不是免费的。

要设置基本认证,请按以下步骤进行。首先安装必要的包。

 pip install dash==0.21.1
pip install dash-auth==1.0.0

随后设置您希望在应用中使用的用户名与密码对。

 VALID_USERNAME_PASSWORD_PAIRS = [
    ['hello', 'world']
]

一旦设置了用户名密码对,Dash 中的 dash_auth.BasicAuth 实用工具将为您处理身份验证。您只需将密码对和您的应用名称传给 dash_auth.BasicAuth 即可。

 app = dash.Dash('auth')
auth = dash_auth.BasicAuth(
    app,
    VALID_USERNAME_PASSWORD_PAIRS
)

Dash 应用登录

在 Heroku 上托管仪表板

在 Heroku 上托管您的仪表板相当容易,但需要几个步骤。

首先,创建一个目录来保存项目的所有文件。在 Ubuntu 上可以使用 mkdir 命令。

$ mkdir my_dash_app
$ cd my_dash_app

接下来,用 git 和 virtualenv 初始化该文件夹。Git 用于版本控制,virtualenv 使我们能够创建一个虚拟环境来保存所有 Python 依赖项。创建环境后,使用 source 命令激活它。

$ git init
$ virtualenv venv
$ source venv/bin/activate

然后,我们安装构建 Dash 应用所需的所有包:

$ pip install dash
$ pip install dash-renderer
$ pip install dash-core-components
$ pip install dash-html-components
$ pip install plotly

要提供 Dash 应用服务,我们需要一个 Python Web 服务器。在生产环境中切勿使用 Flask 的开发服务器。我们使用 Gunicorn Web 服务器来完成此功能。按如下所示安装它:

$ pip install gunicorn

接下来,我们需要在文件夹中创建几个文件:

  1. app.py,我们将在其中编写 dash 应用。
  2. .gitignore,确保不必要的文件不会被推送到生产环境
  3. requirements.txt,包含所有 Python 依赖及其版本。
  4. 用于部署的 Procfile。

将以下内容添加到 app.py。这只是一个示例,您也可以使用自己的 Dash 仪表板。

import os
import dash
import dash_core_components as dcc
import dash_html_components as html
app = dash.Dash(__name__)
server = app.server
app.layout = html.Div([
    html.H2('Hello World'),
    dcc.Dropdown(
        id='dropdown',
        options=[{'label': i, 'value': i} for i in ['LA', 'NYC', 'MTL']],
        value='LA'
    ),
    html.Div(id='display-value')
])
@app.callback(dash.dependencies.Output('display-value', 'children'),
              [dash.dependencies.Input('dropdown', 'value')])
def display_value(value):
    return 'You have selected "{}"'.format(value)
if __name__ == '__main__':
    app.run_server(debug=True)

需要再次提醒的是,从本质上讲,Dash 应用也是一个 Flask 应用。为了部署,我们需要访问 Flask 应用实例。Dash 允许我们通过以下方式实现:

app.server
app = dash.Dash(__name__)
server = app.server

在 .gitignore 文件中添加您不希望推送到生产环境的文件。一个不错的 Python .gitignore 可在 Github 上获取。

现在在 Procfile 中指定部署信息。我们使用 web 变量指定服务器为 gunicorn。同时使用 app 变量指定应用细节。app 指的是文件名 app.py,server 指的是该文件中的 server 变量。

web: gunicorn app:server

我们还需要将 Python 依赖写入 requirements 文件。Heroku 会在部署时安装它们。

pip freeze > requirements.txt

接下来的步骤假设您已有 Heroku 账户并安装了 Heroku CLI。如果尚未完成,请前往 https://www.heroku.com 进行设置。

下一步是在终端中创建一个 Heroku 应用并添加我们所有的应用包。提交更改后,将应用推送到 heroku 的 master 分支。该命令的输出将包含您在 Heroku 上的 Dash 在线应用链接。

$ heroku create your-app-name
$ git add .
$ git commit -m 'Your-commit-message'
$ git push heroku master

这是一篇关于使用 Plotly 的 Dash 以纯 Python 构建仪表板的入门介绍。要了解更多 Dash 内容,请访问官方文档。

如果您有兴趣进一步学习 Python,请查看我们的Python 入门教程和面向数据科学的中级 Python课程。

主题