作者介绍

莲石东路@乌森

心之所向,无界成长。从底层架构到应用实战,聊聊炼数成金背后的故事。

持续更新数据治理、数据科学、数据可视化、空间计算系列文章。

“数据人创作者联盟” 成员


上一篇介绍了python数据可视化的Dash模块,演示了如何生成静态图表,本篇进入交互式图表部分。用Dash构建一个交互式数据可视化应用只需要两样东西,交互控件和回调函数。


01 交互控件


dash在其官方依赖库dash_core_components中内置了众多常见网页小部件,是我们实现交互式所依托的重要元素。


from dash import Dash
import dash_core_components as dcc
import dash_html_components as html
app = Dash() 
app.layout = html.Div([  
   html.Label('单选下拉菜单'),
 
   html.Br(),
 
   dcc.Dropdown(
     
       options=[
         
           {'label': 'beijing', 'value': 'BJ'},
       
           {'label': 'shanghai', 'value': 'SH'}        ],
   
       value='BJ'  # 默认选中
   ),
   html.Label('多选下拉菜单'),
 
   html.Br(),
   
   dcc.Dropdown(
       options=[    
           {'label': 'beijing', 'value': 'BJ'},
       
           {'label': 'shanghai', 'value': 'SH'}        ],
       
    value=['BJ', 'SH'],
       
    multi=True   # 是否多选
 
   ),
   
   html.Label('单选按钮'),
   html.Br(),    
   dcc.RadioItems(
       
       options=[
           
           {'label': 'beijing', 'value': 'BJ'},
         
           {'label': 'shanghai', 'value': 'SH'}
     
       ],
       
       value='BJ'
   
   ),
   
   html.Label('复选按钮'),
   
   html.Br(),
   
   dcc.Checklist(
       
       options=[
           
           {'label': 'beijing', 'value': 'BJ'},
           
           {'label': 'shanghai', 'value': 'SH'}       ],
       
       value=['BJ', 'SH']
   
   ),
   
   html.Label('文本输入框'),
   
   html.Br(),
   
   dcc.Input(
       
       value='BJ',
       
       type='text'
   
   ),
   
   html.Br(),
   
   html.Label('滑动块'),
   
   html.Br(),
   
   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': 1})
if __name__ == '__main__':    
   app.run_server()


02 回调函数


dash高度封装了react.js,我们可以不用编写js代码即可完成前端与后端之间的异步交互。

from dash import Dash
import dash_html_components as html
import dash_core_components as dcc
from dash.dependencies import Input, Output
app = Dash()

province2city_dict = {
   '四川省': '成都市',    
   '陕西省': '西安市',
   
   '广东省': '广州市'
}
app.layout = html.Div(    
   [
       
       html.H1('根据省名查询省会城市:'),
       
       html.Br(),
       
       dcc.Dropdown(
           
           id='province',  # 第一个id,输入的地方
           
           options=[
               
               {'label': '四川省', 'value': '四川省'},
               
               {'label': '陕西省', 'value': '陕西省'},
               
               {'label': '广东省', 'value': '广东省'}
           
           ],
           
           value='四川省'
       
       ),
       
       html.P(id='city')   # 第二个id,输出的地方
   ]
   
)
@app.callback(Output('city', 'children'), Input('province', 'value'))  # 定义了哪个输入对应哪个输出

def province2city(province):    
   return province2city_dict[province]

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


03 交互式图表


有了交互控件和回调函数的知识,将两者结合起来,我们可以构建一个交互式的图表。例子如下:

import pandas as pd
import numpy as np
from dash import Dash, dependencies
import dash_core_components as dcc
import dash_html_components as html
import plotly.graph_objs as go

app = Dash()

# 数据载入
df = pd.read_csv('https://raw.githubusercontent.com/ffzs/dataset/master/insurance.csv')
app.layout = html.Div([    
   html.Div([
       
       html.Label('Gender'),
       
       html.Div([
           
           dcc.Dropdown(   # 功能性组件,设定id值作为标签关联callback函数中的标签
               
               id='gender',
             
               options=[{'label': i, 'value': i} for i in ['female', 'male']],
               
               value='female'),
       
       ]),

       html.Label('Color'),        
       html.Div([
           
           dcc.Dropdown(
               
               id='color',
               
               options=[{'label': i, 'value': i} for i in ['region', 'smoker', 'children']],
               
               value='region'),
       
       ]),
   
   ]),

   html.Div([        
       dcc.Graph(id='scatter')    # 关联graph
   
   ])
   
])
# 对callback函数进行设置,与上面的对应,将数据return回对应id的Graph
@app.callback(    
   dependencies.Output('scatter', 'figure'),
   
   [dependencies.Input('gender','value'), dependencies.Input('color','value')]
   
)
def update_scatter(value_gender, value_color):    
   grouped = df.groupby('sex')  # 以性别分组
   
   data = grouped.get_group(value_gender)  # 获取选取的性别为变量
   
   color_class = pd.Categorical(data[value_color])   # 将颜色分类数据明确化
   
   s = [(np.sqrt(i)+2) for i in data['age']]   # 将年龄数据开方用大小表示用以区别年龄大
       
   trace = go.Scatter(
       
       x=data["bmi"],
       
       y=data["charges"],
       
       mode='markers',
       
       marker=dict(
           
           size=s,
           
           sizemode='diameter',
           
           sizeref=0,
           
           color=color_class.codes,
           
           colorscale='Earth'
       
       )
   
   )

   layout = go.Layout(margin=dict(l=20, r=20, t=0, b=30))    
   fig = go.Figure(data=[trace], layout=layout)
   
   return fig

if __name__ == '__main__':    
   app.run_server()  # 运行app




点赞(898) 打赏

评论列表 共有 0 条评论

暂无评论
立即
投稿

微信公众账号

微信扫一扫加关注

发表
评论
返回
顶部