Python的Web可视化框架Dash(3)---布局

【Dash系列】Python的Web可视化框架Dash(1)---简介
【Dash系列】Python的Web可视化框架Dash(2)---安装
【Dash系列】Python的Web可视化框架Dash(3)---布局设置
【Dash系列】Python的Web可视化框架Dash(4)---基本回调
【Dash系列】Python的Web可视化框架Dash(5)---状态和预更新
【Dash系列】Python的Web可视化框架Dash(6)---交互和过滤
【Dash系列】Python的Web可视化框架Dash(7)---回调共享
【Dash系列】Python的Web可视化框架Dash(8)---核心组件

本节通过6个独立的示例,介绍Dash应用程序的基本使用方法



Dash应用程序由两部分组成。第一部分是布局(layout),描述应用程序的设计样式;第二部分描述了应用程序的交互性。

Dash为应用程序的所有可视化组件,提供了Python类,在dash_core_components库和dash_html_components库中,进行组件的维护。当然,也可以使用 JavaScript 和 React.js 构建自己的组件。

导入本章所有用到的包,下文不再说明

import pandas as pd
import plotly.graph_objs as go
import dash
import dash_core_components as dcc                  # 交互式组件
import dash_html_components as html                 # 代码转html
from dash.dependencies import Input, Output         # 回调
from jupyter_plotly_dash import JupyterDash         # Jupyter中的Dash,如有疑问,见系列文章第2篇【安装】


一、第一个Dash

(一) 代码

app = JupyterDash('Hello Dash', )
app.layout = html.Div(
    children = [
        html.H1('你好,Dash'),
        html.Div('''Dash: Python网络应用框架'''),
        dcc.Graph(
            id='example-graph',
            figure = dict(
                data = [{'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': '北京'},
                        {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': '上海'}],
                layout = dict(title = 'Dash数据可视化')
            )
        )
    ]
)

app

(二) 效果图

(三) 说明

  1. 布局 layouthtml.Divdcc.Graph 这样的组件树组成;

  2. Dash是 声明式 的,通过关键字参数描述组件。即Dash主要通过属性描述应用,如 style、className、id等;

  3. dash_html_components 库为每个HTML标签都提供了对应的组件。本例中:html.H1(children='Hello Dash')可以生成<h1>你好,Dash</h1>这样的HTML语句。并非所有组件都使用纯HTML语言;

  4. dash_core_components 这种交互式高阶组件库,是由JavaScript、HTML和CSS编写,并由React.js库生成,用于设置互动性图表组件,如控件、图形等,其语法类似Plotly;

  5. 按照惯例,children 始终是第一个属性,可以省略,即 html.H1(children='Hello Dash')html.H1('Hello Dash')相同,本例中,声明了3次,实际上都可以忽略。另外,它还可以包含字符串、数字、单个组件或组件列表。

二、自定义HTML文本样式

(一) 代码

app = JupyterDash('Hello Dash Style')
colors = dict(background = '#111111', text = '#7FDBFF')

app.layout = html.Div(
    style = dict(backgroundColor = colors['background']),
    children = [
        html.H1(
            children='你好,Dash',
            style = dict(textAlign = 'center', color = colors['text'])),
        html.Div(
            children='Dash:Python网络应用框架',
            style = dict(textAlign = 'center', color = colors['text'])),
        dcc.Graph(
            id='example-graph-2',
            figure = dict(
                data = [{'x': [1, 2, 3], 'y': [4, 1, 2], 'type': 'bar', 'name': '北京'},
                        {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': '天津'}],
                layout = dict(
                    plot_bgcolor = colors['background'], 
                    paper_bgcolor = colors['background'],
                    font = dict(color = colors['text'])
                )
            )
        )
    ]
)

app

(二) 效果图

(三) 说明

  1. dash_html_components 库除了为HTML参数提供了关键字外,还为每个HTML标签提供了组件类;
  2. 示例中,使用 style 属性修改了 html.Divhtml.H1components 行内样式;
  3. dash_html_componentsHTML 属性,与 HTML 属性之间存以下几点差异:
  • HTML中的style属性是以分号分隔的字符串;Dash用的是字典;
  • Dash的style字典键是 camelCased(驼峰式) 命名法,HTML 中的 text-align,在style字典中为 textAlign
  • HTMLclass 属性,对应Dash中的 className
  • HTML 的子项是通过 children关键字参数指定的,按照惯例,这始终是第一个参数,经常被省略;
  • 除了上述外,其他所有HTML属性与标签,在Python中都有效。

三、可重复使用的组件

(一) 代码

# 数据源:美国农业出口(2011年)
df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/'
    'c78bf172206ce24f77d6363a2d754b59/raw/'
    'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'
    'usa-agricultural-exports-2011.csv')

# 定义表格组件
def create_table(df, max_rows=12):
    """基于dataframe,设置表格格式"""
    
    table = html.Table(
        # Header
        [
            html.Tr(
                [
                    html.Th(col) for col in df.columns
                ]
            )
        ] +
        # Body
        [
            html.Tr(
                [
                    html.Td(
                        df.iloc[i][col]
                    ) for col in df.columns
                ]
            ) for i in range(min(len(df), max_rows))
        ]   
    )
    return table

# 设置Dash应用程序
app = JupyterDash('Defining Components')
app.layout = html.Div(
    children = [
        html.H4(children = '美国农业出口数据表(2011年)'),
        create_table(df)
    ]
)
app

(二) 效果图

(三) 说明

  1. 在Python中定义方法,Dash通过调用,可以创建复杂的可重用组件,如表格等,无需切换上下文或语言;
  2. 本示例实现的功能,是从Pandas的数据帧生成“表格”。

四、可视化散点图

(一) 代码

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

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

app

(二) 效果图

(三) 说明

  1. dash_core_components 库包含一个名为的组件Graph,其使用开源JavaScript图形库plotly.js ,呈现交互式数据可视化;
  2. Plotly.js 支持超过35种图表类型,并以矢量质量SVG和高性能WebGL的方式呈现图表;
  3. dash_core_components.Graph 组件的参数 figure ,与开放源码的 Python 图形库 Plotly 中的参数 figure使用方法,都是一样的;
  4. 这些图表具有互动性和响应性:
  • 将鼠标悬停在点上以查看其值;
  • 单击图例项以切换轨迹;
  • 单击并拖动以缩放;
  • 按住shift后单击并拖动,可以平移图表;

五、Markdown文本

(一) 代码

app = JupyterDash('Markdown')
text_notes = '''
### Dash和Markdown
Dash应用程序可以用Markdown编写。Dash使用 Markdown 的CommonMark规范。

如果这是你对Markdown的第一次介绍,请查看他们的[60 Second Markdown Tutorial](http://commonmark.org/help/)!
'''

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

app

(二) 效果图

(三) 说明

  1. 虽然Dash通过 dash_html_components 库可以实现文本编写,但在HTML中编写文本,比较繁琐,需要写入大量的格式化文本,推荐使用库中的Markdown组件;
  2. Dash使用 MarkdownCommonMark规范;

六、核心组件

(一) 代码

app = JupyterDash('Core Components')
app.layout = html.Div([
    html.Label('下拉菜单'),
    dcc.Dropdown(
        options = [{'label': '北京', 'value': '北京'},
                   {'label': '天津', 'value': '天津'},
                   {'label': '上海', 'value': '上海'}],

        value = '北京'),
    
    html.Label('多选下拉菜单'),
    dcc.Dropdown(
        options = [{'label': '北京', 'value': '北京'},
                   {'label': '天津', 'value': '天津'},
                   {'label': '上海', 'value': '上海'}],
        value = ['北京', '上海'],
        multi = True),
    
    html.Label('单选钮'),
    dcc.RadioItems(
        options = [{'label': '北京', 'value': '北京'},
                   {'label': '天津', 'value': '天津'},
                   {'label': '上海', 'value': '上海'}],
        value = '北京'),
    
    html.Label('多选框'),
    dcc.Checklist(
        options = [{'label': '北京', 'value': '北京'},
                   {'label': '天津', 'value': '天津'},
                   {'label': '上海', 'value': '上海'}],
        value=['北京', '上海']),
    
    html.Label('Text Input'),
    dcc.Input(value = '天津', type = 'text'),
    
    html.Label('文本输入'),
    dcc.Slider(
        min = 0, max = 9, value = 5,
        marks = {i: '标签 {}'.format(i) if i == 1 else str(i) for i in range(1, 6)})
],style={'columnCount': 2})

app

(二) 效果图

(三) 说明

  1. 本示例中,展示了下拉列表单选、下拉列表多选、单选按钮、多选按钮、文本输入框、滑动条;
  2. dash_core_components 包含一系列高级别的组件,如下拉列表、图形、Markdown文本等;
  3. 与所有Dash组件一样,这些组件都是声明式的,组件的关键字参数也一样,每个选项都可以进行配置;
  4. Dash核心组件库中,可以查看所有可用的组件。

七、小结

  1. Dash组件是声明式的,在实例化关键字参数时,可设置配置项。通过调用help,可以查看Dash组件及其可用参数的更多信息;
help(dcc.Dropdown)
  1. 总结
  • 布局(layout)用来设置Dash应用程序的样式,是结构化的树状组件;
  • dash_html_components 库提供了所有的HTML标签和关键字参数,用来设置HTML属性,如style、className、id等;
  • dash_core_components 库生成了更高级别的组件,如控件和图形;
  • 具体参考官方文档:dash_core_componentsdash_html_components
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 211,884评论 6 492
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 90,347评论 3 385
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 157,435评论 0 348
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 56,509评论 1 284
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 65,611评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,837评论 1 290
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,987评论 3 408
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 37,730评论 0 267
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,194评论 1 303
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,525评论 2 327
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,664评论 1 340
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,334评论 4 330
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,944评论 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,764评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,997评论 1 266
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,389评论 2 360
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,554评论 2 349