plotly-dash

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

  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(即上下結(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:

  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.

下面的數(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:

  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(獨(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”.

  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 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:

  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 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>

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末椎木,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子博烂,更是在濱河造成了極大的恐慌香椎,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,277評論 6 503
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件禽篱,死亡現(xiàn)場離奇詭異畜伐,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)躺率,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,689評論 3 393
  • 文/潘曉璐 我一進(jìn)店門烤礁,熙熙樓的掌柜王于貴愁眉苦臉地迎上來讼积,“玉大人,你說我怎么就攤上這事脚仔∏谥冢” “怎么了?”我有些...
    開封第一講書人閱讀 163,624評論 0 353
  • 文/不壞的土叔 我叫張陵鲤脏,是天一觀的道長们颜。 經(jīng)常有香客問我,道長猎醇,這世上最難降的妖魔是什么窥突? 我笑而不...
    開封第一講書人閱讀 58,356評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮硫嘶,結(jié)果婚禮上阻问,老公的妹妹穿的比我還像新娘。我一直安慰自己沦疾,他們只是感情好称近,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,402評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著哮塞,像睡著了一般刨秆。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上忆畅,一...
    開封第一講書人閱讀 51,292評論 1 301
  • 那天衡未,我揣著相機(jī)與錄音,去河邊找鬼家凯。 笑死缓醋,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的绊诲。 我是一名探鬼主播改衩,決...
    沈念sama閱讀 40,135評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼驯镊!你這毒婦竟也來了葫督?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,992評論 0 275
  • 序言:老撾萬榮一對情侶失蹤板惑,失蹤者是張志新(化名)和其女友劉穎橄镜,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體冯乘,經(jīng)...
    沈念sama閱讀 45,429評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洽胶,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,636評論 3 334
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片姊氓。...
    茶點(diǎn)故事閱讀 39,785評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡丐怯,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出翔横,到底是詐尸還是另有隱情读跷,我是刑警寧澤,帶...
    沈念sama閱讀 35,492評論 5 345
  • 正文 年R本政府宣布禾唁,位于F島的核電站效览,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏荡短。R本人自食惡果不足惜丐枉,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,092評論 3 328
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望掘托。 院中可真熱鬧瘦锹,春花似錦、人聲如沸闪盔。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,723評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽锭沟。三九已至抽兆,卻和暖如春识补,著一層夾襖步出監(jiān)牢的瞬間族淮,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,858評論 1 269
  • 我被黑心中介騙來泰國打工凭涂, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留祝辣,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,891評論 2 370
  • 正文 我出身青樓切油,卻偏偏與公主長得像蝙斜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子澎胡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,713評論 2 354

推薦閱讀更多精彩內(nèi)容