使用Dash开发交互式数据可视化网页--响应式编程

简介: 交互性后续的操作前,需要安装如下Python包pip install dash==0.20.0 # The core dash backendpip install dash-renderer==0.

交互性

后续的操作前,需要安装如下Python包

pip install dash==0.20.0  # The core dash backend
pip install dash-renderer==0.11.2  # The dash front-end
pip install dash-html-components==0.8.0  # HTML components
pip install dash-core-components==0.18.1  # Supercharged components
pip install plotly --upgrade  # Plotly graphing library used in examples

第一部分
完成了整体布局,但是基本都是静态图形,无法体现dash交互性数据探索特性。这一部分则是让图形能够动起来,对我们的操作有所回应。

import dash
from dash.dependencies import Input, Output
import dash_core_components as dcc
import dash_html_components as html

app = dash.Dash()

app.layout = html.Div([
    dcc.Input(id='my-id', value='initial vale', 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')]
)
def update_output_div(input_value):
    return 'you\'ve entered "{}"'.format(input_value)

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

运行之后会的界面只有一个dcc.Input提供的输入框,但是这个输入框是输入后,是可以改变页面中的文字。那么这个是如何实现的呢?

我们的应用界面的输入和输出是通过app.callback装饰器进行声明。

在Dash中,应用的输入输出其实就是某个组件的属性(properties)。因此,Output(component_id='my-div', component_property='children')就可以解释为,将值输出到ID为my-div的HTML组件的children的参数中,而[Input(component_id='my-id', component_property='value')]则表明输入时来自于ID为my-idvalue参数。

随着输入的值的改变,装饰器会调用函数update_output_div生成新值。这其实有点像Excel,当你写好一个函数后,修改原来值会产生新的值,这种编程方法叫做"Reactive Programming",应该可以翻译为响应式编程吧.

让我们更进一步,看看使用Slider组件加上响应式编程后,图片是如何动起来. 数据和之前使用的一致,之前是展示了所有年份,不同洲的国家的GDP分布情况。而这里则可以使用滑动栏的方式,逐年查看。

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go
import pandas as pd

df = pd.read_csv(
    'https://raw.githubusercontent.com/plotly/'
    'datasets/master/gapminderDataFiveYear.csv')

app = dash.Dash()

app.layout = html.Div([
    dcc.Graph(id = 'graph-with-slider'),
    dcc.Slider(
        id = 'years-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()}
    )
])

@app.callback(
    dash.dependencies.Output(component_id = 'graph-with-slider', component_property = "figure"),
    [dash.dependencies.Input('years-slider', 'value')]
)
def update_figure(selected_year):
    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()

首先是在布局中设置了两个占位组件,这两个占位组件一个用于提供年份用于筛选,一个用于则是展示输出。然后update_figure接受值返回对应的图形对象,最后展示到浏览器中。

Dash应用在启动的时候会加载数据,因此当用户访问应用的时候,数据已经在内存中,随后用户的交互操作就能得到及时的响应。当然callback函数不会修改原始数据,它仅仅是在内存中创建新的拷贝而已。

多个输入值

上一节只是单个输入单个输出,在Dash中,每个Output,都可以由多个Input。这一部分则是介绍通过加入更多调节组件多角度地展示数据。这里用到了五个调节组件,为2个Dropdown, 2个RadioItems和1个Slider

import dash
from dash.dependencies import Input, Output
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()

df = pd.read_csv(
    'https://gist.githubusercontent.com/chriddyp/'
    'cb5392c35661370d95f300086accea51/raw/'
    '8e0768211f6b747c0db42a9ce9a0937dafcbd8b2/'
    'indicators.csv')

available_indicators = df['Indicator Name'].unique()

app.layout = html.Div([
    html.Div([
        html.Div([
            dcc.Dropdown(
                id='xaxis-column',
                options=[{'label':i, 'value':i} for i in available_indicators],
                value = 'Fertility rate, total(births per woman)'
                ),
            dcc.RadioItems(
                id = 'xaxis-type',
                options = [{'label':i, 'value':i} for i in ['Liner','Log']],
                value = 'Liner',
                labelStype={'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(year)'
            ),
            dcc.RadioItems(
                id = 'yaxis-type',
                options = [{'label':i, 'value':i} for i in ['Liner','Log']],
                value = 'Liner',
                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()}
    )
])

@app.callback(
    Output('indicator-graphic','figure'),
    [Input('xaxis-column','value'),
     Input('yaxis-column','value'),
     Input('xaxis-type','value'),
     Input('yaxis-type','value'),
     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 == 'Liner' else 'log'
            },
            yaxis={
                'title': yaxis_column_name,
                'type': 'linear' if yaxis_type == 'Liner' else 'log'
            },
            margin={'l':40, 'b':40,'t':10,'r':0},
            hovermode='closest'
        )
    }

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

和单个输入区别不大,就是输入多了,要写的代码多了,写代码的时候可能会写错而已。如果有多个输出的需求,只要定义多个callback函数即可。

第二部分小节

Dash应用使用装饰器callback进行响应式编程。回调函数根据component_idcomponent_property从不同组件中获取输入值,然后其所装饰的函数进行计算后,将值返回装饰器,最后将计算结果输出到指定组件中。

目录
相关文章
|
6月前
|
数据可视化 搜索推荐 API
一款功能强大的Unity数据可视化图表库
今天大姚分享一款免费(基于MIT License协议)、开源、功能强大、简单易用、可配置的Unity数据可视化图表库:XCharts。
122 1
|
1月前
|
编解码 数据可视化 前端开发
如何使用 D3.js 创建一个交互式的地图可视化?
如何使用 D3.js 创建一个交互式的地图可视化?
|
6月前
|
数据可视化 JavaScript 架构师
D3.js实战:数据可视化高级技巧实例应用
本文介绍了D3.js入门,包括创建HTML文件引入库、绘制简单线图、柱状图和饼图。示例展示了数据绑定、交互性和动画效果,如柱状图的悬停效果和线图的数据平滑过渡。此外,还提及力导向图和地图可视化的实现,以及使用Enter, Update, Exit模式进行动态更新。最后提到了复杂图表和高级技巧,如使用组件库、动画、交互性和性能优化。
118 0
|
5月前
|
数据可视化 大数据 API
【推荐100个unity插件之22】基于UGUI的功能强大的简单易用的Unity数据可视化图表插件——XCharts3.0插件的使用
【推荐100个unity插件之22】基于UGUI的功能强大的简单易用的Unity数据可视化图表插件——XCharts3.0插件的使用
174 0
|
6月前
|
数据可视化 前端开发 JavaScript
探秘D3.js:数据可视化交互式图表与效果
数据可视化已经成为如今大数据时代的重要工具之一。它不仅可以更直观地呈现数据,还可以帮助人们更好地理解数据背后的含义。而D3.js则作为目前最流行的数据可视化库之一,其强大的功能和灵活性广受开发者青睐。本文将介绍如何使用D3.js创建交互式图表和可视化效果,以及如何利用其强大的API来进行个性化定制。
445 0
|
6月前
|
数据可视化 JavaScript 前端开发
D3.js的交互式图表和可视化效果
在当今数据爆炸的时代,有一个强大的工具可以帮助我们更好地理解和使用数据:D3.js。D3.js是一个流行的JavaScript库,用于创建交互式图表和可视化效果。本文将介绍D3.js的基本特性以及如何使用它来创建高质量的数据可视化。
|
前端开发 数据可视化 JavaScript
使用Dash快速构建你的数据可视化前端
使用Dash快速构建你的数据可视化前端
521 0
|
数据采集 Web App开发 数据可视化
使用Python和Puppeteer渲染框架进行数据可视化
使用Python和Puppeteer渲染框架进行数据可视化
|
数据可视化 前端开发 JavaScript
前端数据可视化的工具和库
前端数据可视化的工具和库
325 0
|
数据可视化 前端开发 JavaScript
前端封装库/工具库的数据可视化之D3.js
在现代前端开发中,数据可视化是一个非常重要的领域。其中,D3.js 是一个备受欢迎的 JavaScript 数据可视化库。
813 0