dash第一章:dash的基本组件

本教程将通过六个独立的小应用带你了解到Dash的一个基本方法:布局。


Dash包括两个部分,一个是它的"layout",用来决定这个可视化面板看起来像什么;另一个部分是设置交互内容的,将在下一章讲解。

注:这份文件中的代码需要通过python文件运行(前提是你安装了dash库)。而如果你使用的是Jupyter,你必须安装JupyterDash才能运行这些代码,安装方法见前面的文章。

你的第一个Dash

好,Dash学习正式开始!!复制下面的代码并运行:

import dash
from dash import dcc
from dash import html
import plotly.express as px
import pandas as pd

#定义一个dash
app = dash.Dash(__name__)

#创建一个数据
df = pd.DataFrame({
    "Fruit":['Apples','Oranges','Bananas','Apples','Oranges','Bananas']
    "Amount":[4,1,2,2,4,5]
    "City":['SF','SF','SF','Montreal','Montreal','Motreal']
})

#用plotly画一个条形图,x轴是蔬菜种类,y轴是数量,条形图按城市分类
fig = px.bar(df , x='Fruit' , y='Amount' , color='City' , barmode = 'group')

#定义dash的格局,html.H1代表1级标题,也就是大标题;里面的html.Div代表一个分割块。
app.layout = html.Div(children = [
    html.H1(children='hello Dash'),
    html.Div(children='''
        Dash: A web application framework for your data.
    '''),

#将你的图片画到html上,并命名
dcc.Graph(
    id = 'example-graph',
    figure=fig
)
])

#运行main函数
if __name__ = '__main__':
    app.run_server(debug=True)

运行上面的代码,你会在终端的到一个本地的web地址,点击进入此web网页你就可以看到你画的第一个Dash图啦!(运行的时间可能会比较长)
下图蓝色部分就是web地址:
image
点击web地址,你会得到如下的网页:
image

注:

  1. layout是由html.Div或者dcc.Graph等元素组成的树构成的。
  2. 对每一个html标签,dash_html_components函数有一个对其都有一个对应的元素。(这句话我也不懂,可能也是在下的英语太差的锅吧)
  3. 并不是所有的组件都是纯HTML的。其中dash_core_components拥有更为高级的交互函数,这些是由JavaScript等语言写出来的。
  4. 每个组件都完全通过关键字属性来描述。Dash是声明性的:您将主要通过这些属性描述您的应用程序。说人话就是你能通过构成这个网页的代码轻松地知道它在干什么。
  5. children变量很特别。按照惯例,它总是第一个属性,这意味着可以忽略它:html.H1(children='Hello Dash')html.H1(“Hello,Dash”)是一样的。它可以包含字符串、数字、单个组件或组件列表。
  6. 应用程序中的字体看起来与此处显示的略有不同。此应用程序使用自定义CSS样式表和Dash Enterprise Design Kit来修改元素的默认样式。您可以在CSS教程中了解有关自定义CSS的更多信息。

来做一点点改变吧

Dash具有热重装性的(hot-reloading),这个特征当你运行app.run_server(debug=True)后会默认开启。当你对你的代码进行改变的时候,Dash会自动更新。
试试将你代码里的标题改成hello world,或者改变x或者y的值,你会发现Dash面板的图像也会发生相应的改变。

如果你不喜欢热重装,你也可以选择关掉它(关掉后代码能运行的更快)。关掉的代码是:app.run_server(dev_tools_hot_reload=False)

HTML组件的更多信息

dash_html_components包含每个html标记的组件类,以及所有html参数的关键字参数。

让我们通过修改组件的内联样式来定制应用程序中的文本,创建一个名为app的文件。使用以下代码:

import dash
from dash import dcc
from dash import html
import plotly.express as px
import pandas as pd

app = dash.Dash(__name__)

#定义背景颜色和文字颜色
colors = {
    'background': '#111111',
    'text': '#7FDBFF'
}


#定义数据
df = pd.DataFrame({
    "Fruit": ["Apples", "Oranges", "Bananas", "Apples", "Oranges", "Bananas"],
    "Amount": [4, 1, 2, 2, 4, 5],
    "City": ["SF", "SF", "SF", "Montreal", "Montreal", "Montreal"]
})

#画条形图
fig = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group")

#更新图片的布局,这里是用的与plotly相关的函数
fig.update_layout(
    plot_bgcolor=colors['background'],
    paper_bgcolor=colors['background'],
    font_color=colors['text']
)

#定义dash的布局
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 your data.', style={
        'textAlign': 'center',
        'color': colors['text']
    }),

    dcc.Graph(
        id='example-graph-2',
        figure=fig
    )
])

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

你运行出来是这个样子吗↓
image

这里,dash_html_components和HTML属性之间有一些差别:

  1. HTML中的style属性是一个分号分隔的字符串。在Dash中,你可以提供一本字典。
  2. style字典中的键是camelCase型的。所以,不是text-align,而是textAlign
  3. HTML中的class属性在Dash中变为了className.
  4. children变量很特别。按照惯例,它总是第一个属性,这意味着可以忽略它:html.H1(children='Hello Dash')html.H1(“Hello,Dash”)是一样的。它可以包含字符串、数字、单个组件或组件列表。

除此之外,所有可用的HTML属性和标记都可以在Python上下文中使用。

可重用组件

通过用Python编写标记,我们可以创建复杂的可重用组件,比如表,而无需切换上下文或语言。
下面是一个从数据帧生成表的快速示例。使用以下代码:

import dash
from dash import dcc
from dash import html
import plotly.express as px
import pandas as pd

# 我们读取Github上的一个公开数据集,来作为接下来实验的原材料
df = pd.read_csv('https://gist.githubusercontent.com/chriddyp/c78bf172206ce24f77d6363a2d754b59/raw/c353e8ef842413cae56ae3920b8fd78468aa4cb2/usa-agricultural-exports-2011.csv')

# 定义一个函数来自动生成表格
# html.Table生成表头,html.Tbody一行一行的添加表内的具体内容

def generate_table(dataframe, max_rows=10):
    return html.Table([ 
        html.Thead(
            html.Tr([html.Th(col) for col in dataframe.columns])
        ),
        html.Tbody([
            html.Tr([
                html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
            ]) for i in range(min(len(dataframe), max_rows))
        ])
    ])


app = dash.Dash(__name__)

app.layout = html.Div([
    html.H4(children='US Agriculture Exports (2011)'),
    generate_table(df)
])

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

我的表格显示出来是这个样子:
image

虽然有点丑,但是成功了: )

更多可视化

dash_core_components库中有一个组件叫做GraphGraph使用JavaScript中的plotly.js开源库呈现交互式数据可视化。plotly.js支持超过35种图表类型,并以矢量SVG和高性能WebGL呈现图表。
Graph组件中的figure参数与plotly.py中使用的figure参数相同。Plotly的开源Python绘图库。你如果想了解更多,可以去plotly的官方文档看看。
下面是一个从pandas数据帧创建散点图的示例。使用以下代码:

import dash
from dash import dcc
from dash import html
import plotly.express as px
import pandas as pd


app = dash.Dash(__name__)

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

fig = px.scatter(df, x="gdp per capita", 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)

我画出来是这样:
image
这幅图是可交互的,当你将鼠标悬停在这些点上是,会看到这个点所表示的信息。单击图例项以切换轨迹,单击并拖动以缩放,按住shift键,然后单击并拖动以平移。

markdown

你还可以用Dash来写markdown!在markdown里再套一层markdown了属于是。运行下面的代码:

import dash
from dash import dcc
from dash import html
import plotly.express as px
import pandas as pd

app = dash.Dash(__name__)

markdown_text = '''
### Dash and Markdown

Dash apps can be written in Markdown.
Dash uses the [CommonMark](http://commonmark.org/)
specification of Markdown.
Check out their [60 Second Markdown Tutorial](http://commonmark.org/help/)
if this is your first introduction to Markdown!
'''

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

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

核心组件

dash_core_components包括一组更高级别的组件,如下拉列表、图表、markdown块等。
与所有Dash组件一样,它们完全是以声明方式描述的。每个可配置的选项都可以作为组件的关键字参数使用。
我们将在整个教程中看到其中的许多组件。您可以在Dash Core Components Gallery中查看所有可用组件。
以下是一些可用的组件。使用以下代码:

import dash
from dash import dcc
from dash import html
import plotly.express as px
import pandas as pd

app = dash.Dash(__name__)

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

        html.Br(),
        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
        ),

        html.Br(),
        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'
        ),
    ], style={'padding': 10, 'flex': 1}),

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

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

        html.Br(),
        html.Label('Slider'),
        dcc.Slider(
            min=0,
            max=9,
            marks={i: 'Label {}'.format(i) if i == 1 else str(i) for i in range(1, 6)},
            value=5,
        ),
    ], style={'padding': 10, 'flex': 1})
], style={'display': 'flex', 'flex-direction': 'row'})

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

你会得到以下一大坨:
image

其中,所有的组件都是传给children这个变量的,以列表的形式存在。

组件名称 功能
html.Label() 用来设置组件的名称
dcc.Dropdown(option= ,value= ,multi=False) 下拉条,option设置下拉条中的选项,value是设置默认值
html.Br() 用来分割各个组件
dcc.RadioItems(options= ,value= ) 用来设置圆形选项
dcc.Checklist(options= ,value= ) 用来形成方形选项
dcc.Input(value= ,type= ) 用来组成输入框
dcc.Slider(min= ,max= ,marks={},value= ) 用来组成滑动条
html.Div(children= ,style={}) 用来形成html,children传入组件信息(列表形式),style用来设置各个组件的排列样式等

帮助

Dash的组件是声明性的:这些组件的每个可配置方面都在实例化期间设置为关键字参数。
在Python控制台中调用任何组件的帮助,以了解有关组件及其可用参数的更多信息。

>>> help(dcc.Dropdown)
class Dropdown(dash.development.base_component.Component)
|  A Dropdown component.
|  Dropdown is an interactive dropdown element for selecting one or more
|  items.
|  The values and labels of the dropdown items are specified in the `options`
|  property and the selected item(s) are specified with the `value` property.
|
|  Use a dropdown when you have many options (more than 5) or when you are
|  constrained for space. Otherwise, you can use RadioItems or a Checklist,
|  which have the benefit of showing the users all of the items at once.
|
|  Keyword arguments:
|  - id (string; optional)
|  - className (string; optional)
|  - disabled (boolean; optional): If true, the option is disabled
|  - multi (boolean; optional): If true, the user can select multiple values
|  - options (list; optional)
|  - placeholder (string; optional): The grey, default text shown when no option is selected
|  - value (string | list; optional): The value of the input. If `multi` is false (the default)
|  then value is just a string that corresponds to the values
|  provided in the `options` property. If `multi` is true, then
|  multiple values can be selected at once, and `value` is an
|  array of items with values corresponding to those in the
|  `options` prop.

当然,你也可以去看它的官方文档。值得注意的是,因为很多图形都是基于plotly的,所以你如果想画出各种吊炸天的图,我建议你也去瞅瞅plotly的官方文档。

总结

Dash的layout决定了Dash看起来像什么。dash_html_components(dash v2.0中的dash.html)库为所有html标记提供类,关键字参数描述html属性,如样式、类和id。dash_core_components库生成更高级别的组件,如控件和图形。反正你在工作时需要啥,回来看看代码就知道了,没有必要搞得那么清楚,只是个工具而已啦。
这里放两个链接:
Dash Core Components Gallery
Dash HTML Components Gallery
Dash教程的下一部分将介绍如何使这些应用程序具有交互性。

如果你喜欢这篇文章,那你肯定喜欢这篇文章。有任何问题可以发在评论区,或者发到我的邮箱:jiang.gucheng@foxmail.com

posted @ 2022-02-01 01:49  蒋古诚  阅读(2891)  评论(0编辑  收藏  举报