Dash Based On Plotly
個(gè)人分類: python
<article class="baidu_pl" style="box-sizing: inherit; outline: 0px; display: block; position: relative; padding-top: 16px; color: rgba(0, 0, 0, 0.75); font-family: -apple-system, "SF UI Text", Arial, "PingFang SC", "Hiragino Sans GB", "Microsoft YaHei", "WenQuanYi Micro Hei", sans-serif; font-size: 14px; font-style: normal; font-variant-ligatures: common-ligatures; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; text-decoration-style: initial; text-decoration-color: initial;">
版權(quán)聲明:本文為博主原創(chuàng)文章做院,未經(jīng)博主允許不得轉(zhuǎn)載。 https://blog.csdn.net/zhangjianjaEE/article/details/76572327
官方文檔: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 backend
pip install dash-renderer==0.7.4 # The dash front-end
pip install dash-html-components==0.7.0 # HTML components
pip install dash-core-components==0.7.1 # Supercharged components
pip 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(內(nèi)部聯(lián)系) 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 dash
import dash_core_components as dcc
import dash_html_components as html
# 實(shí)例化一個(gè)Dash對象
app = dash.Dash()
'''
dash頁面的布局結(jié)構(gòu)為:
1 整個(gè)頁面是一個(gè)div
2 div內(nèi)設(shè)定一個(gè)h1型號的標(biāo)題
3 div內(nèi)包含一個(gè)子div,且內(nèi)容為一行文本
'''
app.layout = html.Div(children=[
html.H1(children='Hello Dash'),
html.Div(children='''
Dash: A web application framework for Python.
'''),
dcc.Graph(
# 唯一標(biāo)識該圖形斧拍,此屬性并不顯示在頁面
id='example-graph',
# 圖形的具體內(nèi)容
figure={
# data是key,值為元素為字典的列表,即圖形的具體數(shù)據(jù)腌且,
# 其中x為橫軸數(shù)據(jù)鏈,y為與x相對應(yīng)的縱軸數(shù)據(jù)鏈何吝,
# type為圖形的類型忆某,name為圖形標(biāo)識
'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'},
],
# 圖形的標(biāo)題
'layout': {
'title': 'Dash Data Visualization'
}
}
)
])
# 入口方法
if __name__ == '__main__':
app.run_server(debug=True)
查看運(yùn)行結(jié)果:
http://localhost:8050
如圖:
Notes
- The layout is composed of a tree of “components” like html.Div and dcc.Graph.
- 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.
- 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.
- Each component is described entirely through keyword attributes. Dash is declarative(公布的宏怔,宣言的): you will primarily(主要地) describe your application through these attributes.
- 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.
- 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(即上下結(jié)構(gòu)). 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 dash
import dash_core_components as dcc
import dash_html_components as html
# 實(shí)例化一個(gè)Dash對象
app=dash.Dash()
#css 屬性字典
colors={'background': '#111111','text': '#7FDBFF'}
# dash頁面的布局結(jié)構(gòu)為:
# 1 整個(gè)頁面是一個(gè)div
# 2 div內(nèi)設(shè)定一個(gè)h1型號的標(biāo)題
# 3 div內(nèi)包含一個(gè)子div,且內(nèi)容為一行文本
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(
# 唯一標(biāo)識該圖形畴椰,此屬性并不顯示在頁面
id='example-graph',
# 圖形的具體內(nèi)容
figure={
# data是key,值為元素為字典的列表,即圖形的具體數(shù)據(jù)鸽粉,
# 其中x為橫軸數(shù)據(jù)鏈斜脂,y為與x相對應(yīng)的縱軸數(shù)據(jù)鏈,
# type為圖形的類型触机,name為圖形標(biāo)識
'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'},
],
# 圖形的標(biāo)題
'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)
查看運(yùn)行結(jié)果帚戳,如圖:
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:
The style property in HTML is a semicolon-separated string. In Dash, you can just supply a dictionary.
The keys in the style dictionary are camelCased. So, instead of text-align, it’s textAlign.
The HTML class attribute is className in Dash.
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.
下面的數(shù)據(jù)源是后續(xù)文檔中都會(huì)用到的,為方便理解后續(xù)的代碼儡首,提前將其聲明出來;
csv格式的數(shù)據(jù)源
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 dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
# 讀取csv文件,read_csv()方法返回值類型為dataFrame
df = pd.read_csv(
'https://gist.githubusercontent.com/chriddyp/'
'c78bf172206ce24f77d6363a2d754b59/raw/'
'c353e8ef842413cae56ae3920b8fd78468aa4cb2/'
'usa-agricultural-exports-2011.csv')
'''
生成表的方法
輸入?yún)?shù):
- dataframe
- 行上限
輸出:
將dataframe中的數(shù)據(jù)轉(zhuǎn)換成表格的形式輸出(行數(shù)<=行上限)
列表之間可以用“+”連接片任,表示列表合并,如:[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\. 整個(gè)頁面由一個(gè)div構(gòu)成
# 2\. div有個(gè)h4尺寸的標(biāo)題
# 3\. 標(biāo)題下面有個(gè)表格
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)
運(yùn)行結(jié)果如圖:
More about Visualization
The dash_core_components library includes a component called Graph.
Graph renders(給予) interactive(互動(dòng)的) 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 dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd
app = dash.Dash()
#讀取csv文件椒舵,返回dataframe
df = pd.read_csv(
'https://gist.githubusercontent.com/chriddyp/' +
'5d1ea79569ed194d432e56108a04d188/raw/' +
'a9f9e8076b837d541398e999dcbac2b2826a81f8/'+
'gdp-life-exp-2007.csv')
'''
頁面布局:
'''
app.layout = html.Div([
# graph組件
dcc.Graph(
# 圖形唯一標(biāo)識,不顯示在頁面
id='life-exp-vs-gdp',
figure={
# 遍歷dataframe中的數(shù)據(jù)约谈,并顯示出來
'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()
運(yùn)行結(jié)果如圖:
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各組件示例用法:
Dropdown(下拉框)
import dash_core_components as dcc
dcc.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 dcc
dcc.Dropdown(
options=[
{'label': 'New York City', 'value': 'NYC'},
{'label': 'Montréal', 'value': 'MTL'},
{'label': 'San Francisco', 'value': 'SF'}
],
multi=True,
value="MTL"
)
Slider(滑動(dòng)條)
import dash_core_components as dcc
dcc.Slider(
min=-5,
max=10,
step=0.5,
value=-3,
)
import dash_core_components as dcc
dcc.Slider(
min=0,
max=9,
marks={i: 'Label {}'.format(i) for i in range(10)},
value=5,
)
RangeSlider(可選范圍的滑動(dòng)條)
import dash_core_components as dcc
dcc.RangeSlider(
count=1,
min=-5,
max=10,
step=0.5,
value=[-3, 7]
)
import dash_core_components as dcc
dcc.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 dcc
dcc.Input(
placeholder='Enter a value...',
type='text',
value=''
)
Checkboxes(復(fù)選框)
import dash_core_components as dcc
dcc.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 dcc
dcc.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 dcc
dcc.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 dcc
dcc.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 dcc
dcc.Markdown('''
Dash and Markdown
Dash 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 dcc
import plotly.graph_objs as go
dcc.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 dash
import dash_html_components as html
import dash_core_components as dcc
app = 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'),
# 復(fù)選框
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'),
# 滑動(dòng)條
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)
運(yùn)行結(jié)果如下:
上面各種組件和html中的各種標(biāo)簽實(shí)現(xiàn)的功能是一樣的,很簡單棱诱,不再贅述泼橘;
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 dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html
# 實(shí)例化一個(gè)dash對象
app = dash.Dash()
# 布局結(jié)構(gòu):
# 1 整個(gè)頁面由一個(gè)div構(gòu)成
# 2 div里面有一個(gè)input輸入框
# 3 input框后面有一個(gè)空的子div
app.layout = html.Div([
dcc.Input(id='my-id', value='initial value', type="text"),
html.Div(id='my-div')
])
# 回調(diào)函數(shù)
@app.callback(
Output(component_id='my-div', component_property='children'),
[Input(component_id='my-id', component_property='value')]
)
# 更新子div
def update_output_div(input_value):
return '您當(dāng)前的輸入為:"{}"'.format(input_value)
if __name__ == '__main__':
app.run_server()
運(yùn)行結(jié)果如下:
注:輸入框和子div顯示的不一致的原因是update_output_div()方法的入?yún)⑹莍nput_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:
The “inputs” and “outputs” of our application interface are described declaratively through the app.callback decorator.
In Dash, the inputs and outputs of our application are simply the properties of a particular(獨(dú)有的迈勋,特別的) 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”.
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.
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.
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.
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 dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd
# 讀取csv文件
df = pd.read_csv(
'https://raw.githubusercontent.com/plotly/'
'datasets/master/gapminderDataFiveYear.csv')
# 創(chuàng)建dash實(shí)例
app = dash.Dash()
'''
布局:
1\. 整個(gè)頁面由一個(gè)div構(gòu)成
2\. div里面有一個(gè)dcc.Graph構(gòu)建的圖形
3\. 圖形下面有一個(gè)滑動(dòng)條
滑動(dòng)條的屬性:
- id:唯一標(biāo)識炬灭,類似與html標(biāo)簽的id屬性,用來唯一定位這個(gè)標(biāo)簽靡菇;
- min:范圍下限
- max:范圍上限
- value:滑動(dòng)條的當(dāng)前值
- step:
- marks:滑動(dòng)條上的刻度名稱
'''
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()}
)
])
# 回調(diào)函數(shù)的寫法:@dash_object_name.callback(xxxxxxx)
@app.callback(
# 圖形作為輸出的載體
dash.dependencies.Output('graph-with-slider', 'figure'),
# 滑動(dòng)條作為輸入的載體
[dash.dependencies.Input('year-slider', 'value')])
# 針對滑動(dòng)操作的回調(diào)函數(shù)重归,輸入?yún)?shù)為滑動(dòng)條的當(dāng)前值
def update_figure(selected_year):
# 從dataframe中過濾出特定年份的數(shù)據(jù)
filtered_df = df[df.year == selected_year]
# 空的列表,作為裝載實(shí)時(shí)數(shù)據(jù)的容器
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
))
# 返回值
# 數(shù)據(jù)和布局
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()
運(yùn)行結(jié)果如圖:
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:
We’re using the Pandas library for importing and filtering datasets in memory.
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.
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.
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 dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd
# 實(shí)例化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\. 頁面是由一個(gè)div構(gòu)成的
2\. div里面有一個(gè)子div
3\. 子div里面有兩個(gè)子div
4\. 最內(nèi)層的兩個(gè)div里面各有dropdown鼻吮,radioItems兩個(gè)組件
'''
app.layout = html.Div([
html.Div([
html.Div([
# 輸入
dcc.Dropdown(
# 唯一標(biāo)識
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()}
)
])
'''
回調(diào)列表
多輸入-單輸出
輸入:
兩個(gè)單選框
兩個(gè)下拉框
一個(gè)滑動(dòng)條
輸出:
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')])
'''
輸入發(fā)生改變時(shí)(單選框,下拉框较鼓,滑動(dòng)條)觸發(fā)的回調(diào)函數(shù)
'''
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()
運(yùn)行結(jié)果如圖:
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 dash
import dash_core_components as dcc
import dash_html_components as html
# 實(shí)例化dash對象
app = dash.Dash('')
'''
布局:
1\. 整個(gè)頁面由一個(gè)div構(gòu)成
2\. div里面有一個(gè)radioItems1組件
3\. radioItems組件下面有個(gè)空的子div1
4\. div1下面有個(gè)radioItems2組件
5\. radioItems2組件下面有個(gè)空的子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')
])
'''
回調(diào)列表
'''
@app.callback(
# 輸出
dash.dependencies.Output('output-a', 'children'),
# 輸入
[dash.dependencies.Input('dropdown-a', 'value')])
# id為dropdown-a的radioItems的值發(fā)生change時(shí)觸發(fā)的回調(diào)函數(shù)
def callback_a(dropdown_value):
return 'You\'ve selected "{}"'.format(dropdown_value)
'''
回調(diào)列表
'''
@app.callback(
# 輸出
dash.dependencies.Output('output-b', 'children'),
# 輸入
[dash.dependencies.Input('dropdown-b', 'value')])
# id為dropdown-b的radioItems的值發(fā)生change時(shí)觸發(fā)的回調(diào)函數(shù)
def callback_b(dropdown_value):
return 'You\'ve selected "{}"'.format(dropdown_value)
if __name__ == '__main__':
app.run_server()
運(yùn)行結(jié)果如圖:
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.
</article>