Dash Based On Plotly

来源:互联网 发布:人工智能 英文介绍 编辑:程序博客网 时间:2024/05/01 01:36

官方文档:https://plot.ly/dash

介绍

Dash is a productive Python framework for building web applications.Written on top of Flask, Plotly.js, and React.js, Dash is ideal for building data visualization apps with highly custom user interfaces in pure Python. It's particuarly suited for anyone who works with data in Python.Through a couple of simple patterns, Dash abstracts away all of the technologies and protocols that are required to build an interactive web-based application. Dash is simple enough that you can bind a user interface around your Python code in an afternoon.Dash apps are rendered in the web browser. You can deploy your apps to servers and then share them through URLs. Since Dash apps are viewed in the web browser, Dash is inherently cross-platform and mobile ready.There is a lot behind the framework. To learn more about how it is built and what motivated dash, watch our talk from Plotcon below or read our announcement letter.Dash is an open source library, released under the permissive MIT license. Plotly develops Dash and offers a platform for deploying, orchestrating, and permissioning dash apps in an enterprise environment

安装

In your terminal, install several dash libraries. These libraries are under active development, so install and upgrade frequently. Python 2 and 3 are supported.
pip install dash==0.17.7  # The core dash backendpip install dash-renderer==0.7.4  # The dash front-endpip install dash-html-components==0.7.0  # HTML componentspip install dash-core-components==0.7.1  # Supercharged componentspip install plotly==2.0.12  # Plotly graphing library used in 

examples

Dash App Layout

Generating HTML with Dash

Dash apps are composed of two parts. The first part is the "layout" of the app and it describes what the application looks like. The second part describes the interactivity(内部联系) of the application.Dash provides Python classes for all of the visual components of the application. We maintain a set of components in the dash_core_components and the dash_html_components library but you can also build your own with JavaScript and React.js.

To get started, create a file named app.py with the following code:

app.py

# coding=UTF-8'''@Author: zhangjian@File: app.py@Date:17-8-1 上午9:33''''''Dash 示例程序'''import dashimport dash_core_components as dccimport dash_html_components as html# 实例化一个Dash对象app = dash.Dash()'''dash页面的布局结构为:1 整个页面是一个div2 div内设定一个h1型号的标题3 div内包含一个子div,且内容为一行文本'''app.layout = html.Div(children=[    html.H1(children='Hello Dash'),    html.Div(children='''        Dash: A web application framework for Python.    '''),    dcc.Graph(        # 唯一标识该图形,此属性并不显示在页面        id='example-graph',        # 图形的具体内容        figure={            # data是key,值为元素为字典的列表,即图形的具体数据,            # 其中x为横轴数据链,y为与x相对应的纵轴数据链,            # type为图形的类型,name为图形标识            'data': [                {'x': [1, 2, 3], 'y': [4, 10, 2], 'type': 'bar', 'name': 'AAPL'},                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': 'IBM'},            ],            # 图形的标题            'layout': {                'title': 'Dash Data Visualization'            }        }    )])# 入口方法if __name__ == '__main__':    app.run_server(debug=True)

查看运行结果:
http://localhost:8050
如图:
这里写图片描述

Notes

  1. The layout is composed of a tree of “components” like html.Div and dcc.Graph.
  2. The dash_html_components library has a component for every HTML tag.it’s so powerful! The html.H1(children=’Hello Dash’) component generates a < h 1>Hello Dash< /h 1>HTML element in your application.
  3. Not all components are pure(单纯的) HTML. The dash_core_components describe higher-level components that are interactive and are generated with JavaScript, HTML, and CSS through the React.js library.
  4. Each component is described entirely through keyword attributes. Dash is declarative(公布的,宣言的): you will primarily(主要地) describe your application through these attributes.
  5. The children property is special. By convention(惯例), it’s always the first attribute which means that you can omit(省略) it: html.H1(children=’Hello Dash’) is the same as html.H1(‘Hello Dash’). Also, it can contain a string, a number, a single component, or a list of components.
  6. The fonts in your application will look a little bit different than what is displayed here. This application is using a custom CSS stylesheet to modify the default styles of the elements. You can learn more in the css tutorial, but for now you can add app.css.append_css({“external_url”: “https://codepen.io/chriddyp/pen/bWLwgP.css“}) to your file to get the same look and feel of these examples.
    By default, the items in your layout are arranged(安排) one on top of the other(即上下结构). You can create different arrangements(安排方式) using CSS and stylesheets in the custom layout arrangements in Dash apps tutorial ;
    More about HTML
    The dash_html_components library contains a component class for every HTML tag as well as keyword arguments for all of the HTML arguments.
    Let’s customize the text in our app.py by modifying the inline styles of the components:

app.py

(modified by new styles)

# coding=UTF-8'''@Author: zhangjian@File: app.py@Date:17-8-1 上午9:33''''''Dash 示例程序'''import dashimport dash_core_components as dccimport dash_html_components as html# 实例化一个Dash对象app=dash.Dash()#css 属性字典colors={'background': '#111111','text': '#7FDBFF'}# dash页面的布局结构为:# 1 整个页面是一个div# 2 div内设定一个h1型号的标题# 3 div内包含一个子div,且内容为一行文本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='example-graph',        # 图形的具体内容        figure={            # data是key,值为元素为字典的列表,即图形的具体数据,            # 其中x为横轴数据链,y为与x相对应的纵轴数据链,            # type为图形的类型,name为图形标识            'data': [                {'x': [1, 2, 3], 'y': [4, 10, 2], 'type': 'bar', 'name': 'AAPL'},                {'x': [1, 2, 3], 'y': [2, 4, 5], 'type': 'bar', 'name': 'IBM'},            ],            # 图形的标题            'layout': {                'title': 'Dash Data Visualization',                'plot_bgcolor': colors['background'],                'paper_bgcolor': colors['background'],                'font': {                    'color': colors['text']                }            }        }    )])# 附加css样式app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})# 入口方法if __name__ == '__main__':    app.run_server(debug=True)

查看运行结果,如图:
这里写图片描述

Notes

In this example, we modified the inline styles of the html.Div and html.H1 components with the style property.html.H1('Hello Dash', style={'textAlign`': 'center', 'color': '#7FDFF'}) is rendered in the Dash application as < h1 style="text-align: center; color: #7FDFF">Hello Dash< /h1>.There are a few important differences between the dash_html_components and the HTML attributes:
  1. The style property in HTML is a semicolon-separated string. In Dash, you can just supply a dictionary.

  2. The keys in the style dictionary are camelCased. So, instead of text-align, it’s textAlign.

  3. The HTML class attribute is className in Dash.

  4. The children of the HTML tag is specified through the children keyword argument.
    Besides that, all of the available HTML attributes and tags are available to you within your Python context.

下面的数据源是后续文档中都会用到的,为方便理解后续的代码,提前将其声明出来;
csv格式的数据源
URL:https://gist.githubusercontent.com/chriddyp/cb5392c35661370d95f300086accea51/raw/8e0768211f6b747c0db42a9ce9a0937dafcbd8b2/indicators.csv
列名:Country Name||Indicator Name||Year||Value
如图:
这里写图片描述

Reusable Components

By writing our markup in Python, we can create complex resuable components like tables without switching contexts or languages.Here's a quick example that generates a Table from a Pandas dataframe. If you don't have Pandas installed, install with pip install pandas.

table.py

# coding=UTF-8'''@Author: zhangjian@File: table.py.py@Date:17-8-1 上午10:51'''import dashimport dash_core_components as dccimport dash_html_components as htmlimport pandas as pd# 读取csv文件,read_csv()方法返回值类型为dataFramedf = pd.read_csv(    'https://gist.githubusercontent.com/chriddyp/'    'c78bf172206ce24f77d6363a2d754b59/raw/'    'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'    'usa-agricultural-exports-2011.csv')'''生成表的方法输入参数:- dataframe- 行上限输出:将dataframe中的数据转换成表格的形式输出(行数<=行上限)列表之间可以用“+”连接,表示列表合并,如:[1,'A']+[2]=[1,'A',2]'''def generate_table(dataframe, max_rows=10):    return html.Table(        # Header        [html.Tr([html.Th(col) for col in dataframe.columns])] +        # Body        [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()# 页面布局:# 1. 整个页面由一个div构成# 2. div有个h4尺寸的标题# 3. 标题下面有个表格app.layout = html.Div(children=[    html.H4(children='US Agriculture Exports (2011)'),    generate_table(df)],style={'background':'gray'})if __name__ == '__main__':    app.run_server(debug=True)

运行结果如图:
这里写图片描述

More about Visualization

The dash_core_components library includes a component called Graph.Graph renders(给予) interactive(互动的) data visualizations using the open source plotly.js JavaScript graphing library. Plotly.js supports over 35 chart types and renders charts in both vector-quality SVG and high-performance(高性能) WebGL.The figure argument in the dash_core_components.Graph component is the same figure argument that is used by plotly.py, Plotly's open source Python graphing library. Check out the plotly.py documentation and gallery to learn more.

graph.py

# coding=utf-8'''@Author: zhangjian@File: graph.py@Date:17-8-1 上午11:25'''import dashimport dash_core_components as dccimport dash_html_components as htmlimport plotly.graph_objs as goimport pandas as pdapp = dash.Dash()#读取csv文件,返回dataframedf = pd.read_csv(    'https://gist.githubusercontent.com/chriddyp/' +    '5d1ea79569ed194d432e56108a04d188/raw/' +    'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+    'gdp-life-exp-2007.csv')'''页面布局:'''app.layout = html.Div([    # graph组件    dcc.Graph(        # 图形唯一标识,不显示在页面        id='life-exp-vs-gdp',        figure={            # 遍历dataframe中的数据,并显示出来            '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.7,                    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()

运行结果如图:
这里写图片描述

Notes

These graphs are interactive and responsive. Hover over points to see their values, click on legend items to toggle traces, click and drag to zoom, hold down shift, and click and drag to pan.

Markdown

While Dash exposes(暴露,曝光) HTML through the dash_html_components library, it can be tedious(乏味的) to write your copy(稿件) in HTML. For writing blocks of text(文本块), you can use the Markdown component in the dash_core_components library.

Core Components

The dash_core_components includes a set a higher-level components like dropdowns, graphs, markdown blocks, and more.Like all Dash components, they are described entirely declaratively. Every option that is configurable is available as a keyword argument of the component.Dash ships with supercharged components for interactive user interfaces. A core set of components, written and maintained by the Dash team, is available in the dash-core-components library.

The source is on GitHub at plotly/dash-core-components.

dash_core_components各组件示例用法:

import dash_core_components as dccdcc.Dropdown(    options=[        {'label': 'New York City', 'value': 'NYC'},        {'label': 'Montréal', 'value': 'MTL'},        {'label': 'San Francisco', 'value': 'SF'}    ],    value='MTL')import dash_core_components as dccdcc.Dropdown(    options=[        {'label': 'New York City', 'value': 'NYC'},        {'label': 'Montréal', 'value': 'MTL'},        {'label': 'San Francisco', 'value': 'SF'}    ],    multi=True,    value="MTL")

Slider(滑动条)

import dash_core_components as dccdcc.Slider(    min=-5,    max=10,    step=0.5,    value=-3,)import dash_core_components as dccdcc.Slider(    min=0,    max=9,    marks={i: 'Label {}'.format(i) for i in range(10)},    value=5,)

RangeSlider(可选范围的滑动条)

import dash_core_components as dccdcc.RangeSlider(    count=1,    min=-5,    max=10,    step=0.5,    value=[-3, 7])import dash_core_components as dccdcc.RangeSlider(    marks={i: 'Label {}'.format(i) for i in range(-5, 7)},    min=-5,    max=6,    value=[-3, 4])Input(输入框)import dash_core_components as dccdcc.Input(    placeholder='Enter a value...',    type='text',    value='')

Checkboxes(复选框)

import dash_core_components as dccdcc.Checklist(    options=[        {'label': 'New York City', 'value': 'NYC'},        {'label': 'Montréal', 'value': 'MTL'},        {'label': 'San Francisco', 'value': 'SF'}    ],    values=['MTL', 'SF'])import dash_core_components as dccdcc.Checklist(    options=[        {'label': 'New York City', 'value': 'NYC'},        {'label': 'Montréal', 'value': 'MTL'},        {'label': 'San Francisco', 'value': 'SF'}    ],    values=['MTL', 'SF'],    labelStyle={'display': 'inline-block'})Radio Items(单选框)import dash_core_components as dccdcc.RadioItems(    options=[        {'label': 'New York City', 'value': 'NYC'},        {'label': 'Montréal', 'value': 'MTL'},        {'label': 'San Francisco', 'value': 'SF'}    ],    value='MTL')import dash_core_components as dccdcc.RadioItems(    options=[        {'label': 'New York City', 'value': 'NYC'},        {'label': 'Montréal', 'value': 'MTL'},        {'label': 'San Francisco', 'value': 'SF'}    ],    value='MTL',    labelStyle={'display': 'inline-block'})

Markdown

import dash_core_components as dccdcc.Markdown('''Dash and MarkdownDash supports [Markdown](http://commonmark.org/help).Markdown is a simple way to write and format text.It includes a syntax for things like **bold text** and *italics*,[links](http://commonmark.org/help), inline `code` snippets, lists,quotes, and more.''')

Markdown(use Markdown languare to format text )

Dash supports Markdown.Markdown is a simple way to write and format text. It includes a syntax for things like bold text and italics, links, inline code snippets, lists, quotes, and more.

Graphs

The Graph component shares the same syntax as the open-source plotly.py library. View the plotly.py docs to learn more.
import dash_core_components as dccimport plotly.graph_objs as godcc.Graph(    figure=go.Figure(        data=[            go.Scatter(x=[1, 2, 3], y=[3, 2, 4], mode='lines'),            go.Scatter(x=[1, 2, 3], y=[4, 1, 5], mode='lines')        ],        layout=go.Layout(            title='Quarterly Results',            showlegend=False,            margin=go.Margin(l=20, r=0, t=40, b=20)        )    ),    style={'height': 300},    id='my-graph')

将这些组件测试一下:

dash_core_components.py

#coding=utf-8'''@Author: zhangjian@File: dash_core_component.py@Date:17-8-1 下午1:16'''################Dropdown################ -*- coding: utf-8 -*-import dashimport dash_html_components as htmlimport dash_core_components as dccapp = dash.Dash()app.layout = html.Div([    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.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.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'    ),    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']    ),    html.Label('Text Input'),    # 输入框    dcc.Input(value='MTL', type='text'),    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={'columnCount': 2})if __name__ == '__main__':    app.run_server(debug=True)

运行结果如下:
这里写图片描述

上面各种组件和html中的各种标签实现的功能是一样的,很简单,不再赘述;

API帮助

Dash components are declarative: every configurable aspect of these components is set during instantiation as a keyword argument. Call help in your Python console on any of the components to learn more about a component and its available arguments;

Summary

The layout of a Dash app describes what the app looks like. The layout is a hierarchical tree of components. The dash_html_components library provides classes for all of the HTML tags and the keyword arguments describe the HTML attributes like style, className, and id. The dash_core_components library generates higher-level components like controls and graphs.

Interactivity

The first part of this tutorial covered the layout of Dash apps. The layout of a Dash app describes what the app looks like. It is a hierarchical tree of components. The dash_html_components library provides classes for all of the HTML tags and the keyword arguments describe the HTML attributes like style, className, and id. The dash_core_components library generates higher-level components like controls and graphs.   The second part of the tutorial describes how to make your Dash apps interactive.

dash_input_output.py

#coding=utf-8'''@Author: zhangjian@File: example.py@Date:17-8-1 下午2:00'''import dashfrom dash.dependencies import Input, Outputimport dash_core_components as dccimport dash_html_components as html# 实例化一个dash对象app = dash.Dash()# 布局结构:# 1 整个页面由一个div构成# 2 div里面有一个input输入框# 3 input框后面有一个空的子divapp.layout = html.Div([    dcc.Input(id='my-id', value='initial value', 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')])# 更新子divdef update_output_div(input_value):    return '您当前的输入为:"{}"'.format(input_value)if __name__ == '__main__':    app.run_server()

运行结果如下:
这里写图片描述
注:输入框和子div显示的不一致的原因是update_output_div()方法的入参是input_value原始的键盘输入;

Notes

Try typing in the text box. The children of the output component updates right away. Let's break down what's happening here:
  1. The “inputs” and “outputs” of our application interface are described declaratively through the app.callback decorator.

  2. In Dash, the inputs and outputs of our application are simply the properties of a particular(独有的,特别的) component. In this example, our input is the “value” property of the component that has the ID “my-id”. Our output is the “children” property of the component with the ID “my-div”.

  3. Whenver an input property changes, the function that the callback decorator wraps will get called automatically. Dash provides the function with the new value of the input property as an input argument and Dash updates the property of the output component with whatever was returned by the function.

  4. The component_id and component_property keywords are optional (there are only two arguments for each of those objects). I have included them here for clarity but I will omit them from here on out for brevity and readability.

  5. Don’t confuse the dash.dependencies.Input object from the dash_core_components.Input object. The former is just used in these callbacks and the latter is an actual component.

  6. Notice how we don’t set a value for the children property of the my-div component in the layout. When the Dash app starts, it automatically calls all of the callbacks with the initial values of the input components in order to populate the initial state of the output components. In this example, if you specified something like html.Div(id=’my-div’, children=’Hello world’), it would get overwritten when the app starts.
    It’s sort of like programming with Microsoft Excel: whenever an input cell changes, all of the cells that depend on that cell will get updated automatically. This is called “Reactive Programming”.
    Remember how every component was described entirely through its set of keyword arguments? Those properties are important now. With Dash interactivity, we can dynamically update any of those properties through a callback function. Frequently we’ll update the children of a component to display new text or the figure of a dcc.Graph component to display new data, but we could also update the style of a component or even the available options of a dcc.Dropdown component!

dash_slider_dpdate_graph.py

(a dcc.Slider updates a dcc.Graph)

# coding=utf-8'''@Author: zhangjian@File: dash_splider_update_graph.py@Date:17-8-1 下午2:40'''import dashimport dash_core_components as dccimport dash_html_components as htmlimport plotly.graph_objs as goimport pandas as pd# 读取csv文件df = pd.read_csv(    'https://raw.githubusercontent.com/plotly/'    'datasets/master/gapminderDataFiveYear.csv')# 创建dash实例app = dash.Dash()'''布局:1. 整个页面由一个div构成2. div里面有一个dcc.Graph构建的图形3. 图形下面有一个滑动条   滑动条的属性:   - id:唯一标识,类似与html标签的id属性,用来唯一定位这个标签;   - min:范围下限   - max:范围上限   - value:滑动条的当前值   - step:   - marks:滑动条上的刻度名称'''app.layout = html.Div([    dcc.Graph(id='graph-with-slider', animate=True),    dcc.Slider(        id='year-slider',        min=df['year'].min(),        max=df['year'].max(),        value=df['year'].min(),        step=None,        marks={str(year): str(year) for year in df['year'].unique()}    )])# 回调函数的写法:@dash_object_name.callback(xxxxxxx)@app.callback(    # 图形作为输出的载体    dash.dependencies.Output('graph-with-slider', 'figure'),    # 滑动条作为输入的载体    [dash.dependencies.Input('year-slider', 'value')])# 针对滑动操作的回调函数,输入参数为滑动条的当前值def update_figure(selected_year):    # 从dataframe中过滤出特定年份的数据    filtered_df = df[df.year == selected_year]    # 空的列表,作为装载实时数据的容器    traces = []    # 遍历    for i in filtered_df.continent.unique():        # 每行        df_by_continent = filtered_df[filtered_df['continent'] == i]        # 从每行中抽取属性值,并添加到列表中        traces.append(go.Scatter(            x=df_by_continent['gdpPercap'],            y=df_by_continent['lifeExp'],            text=df_by_continent['country'],            mode='markers',            opacity=0.7,            marker={                'size': 15,                'line': {'width': 0.5, 'color': 'white'}            },            name=i        ))    # 返回值    # 数据和布局    return {        'data': traces,        'layout': go.Layout(            xaxis={'type': 'log', 'title': 'GDP Per Capita'},            yaxis={'title': 'Life Expectancy', 'range': [20, 90]},            margin={'l': 40, 'b': 40, 't': 10, 'r': 10},            legend={'x': 0, 'y': 1},            hovermode='closest'        )    }if __name__ == '__main__':    app.run_server()

运行结果如图:
这里写图片描述

Notes

In this example, the "value" property of the Slider is the input of the app and the output of the app is the "figure" property of the Graph. Whenever the value of the Slider changes, Dash calls the callback function update_figure with the new value. The function filters the dataframe with this new value, constructs a figure object, and returns it to the Dash application.

There are a few nice patterns in this example:

  1. We’re using the Pandas library for importing and filtering datasets in memory.

  2. We load our dataframe at the start of the app: df = pd.read_csv(‘…’). This dataframe df is in the global state of the app and can be read inside the callback functions.

  3. Loading data into memory can be expensive. By loading querying data at the start of the app instead of inside the callback functions, we ensure that this operation is only done when the app server starts. When a user visits the app or interacts with the app, that data (the df) is already in memory. If possible, expensive initialization (like downloading or querying data) should be done in the global scope of the app instead of within the callback functions.

  4. The callback does not modify the original data, it just creates copies of the dataframe by filtered through pandas filters. This is important: your callbacks should never mutate variables outside of their scope. If your callbacks modify global state, then one user’s session might affect the next user’s session and when the app is deployed on multiple processes or threads, those modifications will not be shared across sessions.

Multiple inputs

In Dash any "Output" can have multiple "Input" components. Here's a simple example that binds 5 Inputs (the value property of 2 Dropdown components, 2 RadioItems components, and 1 Slider component) to 1 Output component (the figure property of the Graph component). Notice how the app.callback lists all 5 dash.dependencies.Input inside a list in the second argument.

multiple inputs.py

#coding=utf-8'''@Author: zhangjian@File: multipleInput.py@Date:17-8-1 下午3:40'''import dashimport dash_core_components as dccimport dash_html_components as htmlimport plotly.graph_objs as goimport pandas as pd# 实例化dash对象app = dash.Dash()# 读取csv文件df = pd.read_csv(    'https://gist.githubusercontent.com/chriddyp/'    'cb5392c35661370d95f300086accea51/raw/'    '8e0768211f6b747c0db42a9ce9a0937dafcbd8b2/'    'indicators.csv')# 获取dataFrame中Indicator Name这一列的所有值available_indicators = df['Indicator Name'].unique()'''布局:1. 页面是由一个div构成的2. div里面有一个子div3. 子div里面有两个子div4. 最内层的两个div里面各有dropdown,radioItems两个组件'''app.layout = html.Div([    html.Div([        html.Div([            # 输入            dcc.Dropdown(                # 唯一标识                id='xaxis-column',                # value为dataframe的INdicator Name列的所有值                options=[{'label': i, 'value': i} for i in available_indicators],                value='Fertility rate, total (births per woman)'            ),            # 输入            dcc.RadioItems(                id='xaxis-type',                # value为Linear||Log                options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],                value='Linear',                labelStyle={'display': 'inline-block'}            )        ],        style={'width': '48%', 'display': 'inline-block'}),        html.Div([            # 输入            dcc.Dropdown(                id='yaxis-column',                options=[{'label': i, 'value': i} for i in available_indicators],                value='Life expectancy at birth, total (years)'            ),            # 输入            dcc.RadioItems(                id='yaxis-type',                options=[{'label': i, 'value': i} for i in ['Linear', 'Log']],                value='Linear',                labelStyle={'display': 'inline-block'}            )        ],style={'width': '48%', 'float': 'right', 'display': 'inline-block'})    ]),    # 输出    dcc.Graph(id='indicator-graphic'),    # 输入    dcc.Slider(        id='year--slider',        min=df['Year'].min(),        max=df['Year'].max(),        value=df['Year'].max(),        step=None,        marks={str(year): str(year) for year in df['Year'].unique()}    )])'''回调列表多输入-单输出输入:两个单选框两个下拉框一个滑动条输出:graph'''@app.callback(    dash.dependencies.Output('indicator-graphic', 'figure'),    [dash.dependencies.Input('xaxis-column', 'value'),     dash.dependencies.Input('yaxis-column', 'value'),     dash.dependencies.Input('xaxis-type', 'value'),     dash.dependencies.Input('yaxis-type', 'value'),     dash.dependencies.Input('year--slider', 'value')])'''输入发生改变时(单选框,下拉框,滑动条)触发的回调函数'''def update_graph(xaxis_column_name, yaxis_column_name,                 xaxis_type, yaxis_type,                 year_value):    dff = df[df['Year'] == year_value]    return {        'data': [go.Scatter(            x=dff[dff['Indicator Name'] == xaxis_column_name]['Value'],            y=dff[dff['Indicator Name'] == yaxis_column_name]['Value'],            text=dff[dff['Indicator Name'] == yaxis_column_name]['Country Name'],            mode='markers',            marker={                'size': 15,                'opacity': 0.5,                'line': {'width': 0.5, 'color': 'white'}            }        )],        'layout': go.Layout(            xaxis={                'title': xaxis_column_name,                'type': 'linear' if xaxis_type == 'Linear' else 'log'            },            yaxis={                'title': yaxis_column_name,                'type': 'linear' if yaxis_type == 'Linear' else 'log'            },            margin={'l': 40, 'b': 40, 't': 10, 'r': 0},            hovermode='closest'        )    }if __name__ == '__main__':    app.run_server()

运行结果如图:
这里写图片描述

Notes

In this example, the update_graph function gets called whenever the value property of the Dropdown, Slider, or RadioItems components change.The input arguments of the update_graph function are the new or current value of the each of the Input properties, in the order that they were specified.Even though only a single Input changes at a time (a user can only change the value of a single Dropdown in a given moment), Dash collects the current state of all of the specified Input properties and passes them into your function for you. Your callback functions are always guarenteed to be passed the representative state of the app.

Multiple Outputs

Each Dash callback function can only update a single Output property. To update multiple Outputs, just write multiple functions.

multipleOutput.py

# coding=utf-8'''@Author: zhangjian@File: multipleOutput.py@Date:17-8-1 下午4:55'''import dashimport dash_core_components as dccimport dash_html_components as html# 实例化dash对象app = dash.Dash('')'''布局:1. 整个页面由一个div构成2. div里面有一个radioItems1组件3. radioItems组件下面有个空的子div14. div1下面有个radioItems2组件5. radioItems2组件下面有个空的子div2'''app.layout = html.Div([    # 输入    dcc.RadioItems(        id='dropdown-a',        options=[{'label': i, 'value': i} for i in ['Canada', 'USA', 'Mexico']],        value='Canada'    ),    # 输出    html.Div(id='output-a'),    # 输入    dcc.RadioItems(        id='dropdown-b',        options=[{'label': i, 'value': i} for i in ['MTL', 'NYC', 'SF']],        value='MTL'    ),    # 输出    html.Div(id='output-b')])'''回调列表'''@app.callback(    # 输出    dash.dependencies.Output('output-a', 'children'),    # 输入    [dash.dependencies.Input('dropdown-a', 'value')])# id为dropdown-a的radioItems的值发生change时触发的回调函数def callback_a(dropdown_value):    return 'You\'ve selected "{}"'.format(dropdown_value)'''回调列表'''@app.callback(    # 输出    dash.dependencies.Output('output-b', 'children'),    # 输入    [dash.dependencies.Input('dropdown-b', 'value')])# id为dropdown-b的radioItems的值发生change时触发的回调函数def callback_b(dropdown_value):    return 'You\'ve selected "{}"'.format(dropdown_value)if __name__ == '__main__':    app.run_server()

运行结果如图:
这里写图片描述

Summary

We've covered the fundamentals of Dash. Dash apps are built off of a set of simple but powerful principles: declarative UIs that are customizable through reactive and functional Python callbacks. Every element attribute of the declarative components can be updated through a callback and a subset of the attributes, like the value properties of the dcc.Dropdown, are editable by the user in the interface.