基于三级联动下拉框的Pandas数据过滤与Plotly可视化实现
问题说明
现有示例DataFrame如下:
import pandas as pd df = pd.DataFrame ({"id": {0: 84, 1: 84, 2: 84, 3: 84, 4: 124}, "Version": { 0: 'SemVer4', 1: 'Timestamps', 2: 'Snapshots', 3: 'Names', 4: 'Numbered Versions'}, "server_Version": {0: 'v1', 1: 'v2', 2: 'api/v1', 3: '1.1.0', 4: 'v4'}, "owner": {0: 'vmware', 1:'microsoft', 2: 'nasa', 3: 'swagger-API', 4:'sqaas'}, "repo_name": {0: 'container-service-extension', 1: 'azure-rest-api-specs', 2: 'api.nasa.gov', 3: 'swagger-ui', 4: 'sqaas'}, "filepath":{0: 'openapi.yaml', 1: 'dapper.json', 2: 'dockstore-webservice/src/main/resources/openapi3/openapi.yaml', 3: 'api/cmd/kubermatic-api/swagger.json', 4: 'cmd/spec/openapi.jsonsqaas'}})
需求如下:
- 实现owner、repo_name、filepath三级联动下拉框,三者依赖关系:owner对应主API所属主体,repo_name是该主体下的仓库名称,filepath是选中仓库内的操作文件路径
- 基于联动过滤后的数据,展示不同年份、月份下
Version与server_Version的使用情况 - 此前在Elasticsearch中实现过类似下拉框,但Kibana存在字段解析问题,目前用Plotly开发但仅能实现单个owner过滤,需要完善三级联动逻辑
Plotly Dash实现三级联动方案
前置说明
原示例DataFrame缺少年月字段,假设数据中已包含year和month列(若没有,可通过数据时间字段提取生成)。以下用Plotly Dash实现完整联动逻辑:
import pandas as pd import plotly.express as px from dash import Dash, dcc, html, Input, Output, State # 初始化Dash应用 app = Dash(__name__) # 假设已添加年月字段到df中 df['year'] = [2023, 2023, 2024, 2024, 2024] df['month'] = [10, 11, 1, 2, 3] app.layout = html.Div([ # 三级下拉框 html.Div([ html.Label('选择Owner:'), dcc.Dropdown( id='owner-dropdown', options=[{'label': o, 'value': o} for o in df['owner'].unique()], placeholder='选择一个Owner' ), ], style={'width': '30%', 'display': 'inline-block', 'margin': '10px'}), html.Div([ html.Label('选择仓库:'), dcc.Dropdown( id='repo-dropdown', placeholder='先选择Owner' ), ], style={'width': '30%', 'display': 'inline-block', 'margin': '10px'}), html.Div([ html.Label('选择文件路径:'), dcc.Dropdown( id='filepath-dropdown', placeholder='先选择仓库' ), ], style={'width': '30%', 'display': 'inline-block', 'margin': '10px'}), # 可视化图表区域 dcc.Graph(id='version-trend-graph') ]) # 回调1:根据选中的Owner更新仓库下拉框选项 @app.callback( Output('repo-dropdown', 'options'), Output('repo-dropdown', 'value'), Input('owner-dropdown', 'value') ) def update_repo_options(selected_owner): if not selected_owner: return [], None filtered_repos = df[df['owner'] == selected_owner]['repo_name'].unique() return [{'label': r, 'value': r} for r in filtered_repos], None # 回调2:根据选中的仓库更新文件路径下拉框选项 @app.callback( Output('filepath-dropdown', 'options'), Output('filepath-dropdown', 'value'), Input('repo-dropdown', 'value'), State('owner-dropdown', 'value') ) def update_filepath_options(selected_repo, selected_owner): if not selected_repo or not selected_owner: return [], None filtered_files = df[(df['owner'] == selected_owner) & (df['repo_name'] == selected_repo)]['filepath'].unique() return [{'label': f, 'value': f} for f in filtered_files], None # 回调3:根据三级选择过滤数据,更新可视化图表 @app.callback( Output('version-trend-graph', 'figure'), Input('owner-dropdown', 'value'), Input('repo-dropdown', 'value'), Input('filepath-dropdown', 'value') ) def update_graph(selected_owner, selected_repo, selected_file): # 逐步过滤数据 filtered_df = df.copy() if selected_owner: filtered_df = filtered_df[filtered_df['owner'] == selected_owner] if selected_repo: filtered_df = filtered_df[filtered_df['repo_name'] == selected_repo] if selected_file: filtered_df = filtered_df[filtered_df['filepath'] == selected_file] # 生成年月维度的Version与server_Version分布图表 fig = px.bar(filtered_df, x='month', y='id', color='Version', facet_col='year', hover_data=['server_Version'], title='不同年月下API Version与server_Version使用情况') return fig if __name__ == '__main__': app.run_server(debug=True)
代码说明
- 三个下拉框通过回调函数实现联动:选中Owner后自动筛选对应仓库,选中仓库后自动筛选对应文件路径
- 最终图表基于三级过滤后的数据,按年份分面、月份为横轴,展示不同Version的分布,hover时可查看对应的server_Version信息
替代可视化库推荐
除Plotly Dash外,以下库也适合实现这类交互式联动可视化:
- Streamlit:语法极简,无需写回调逻辑,通过会话状态即可实现联动,适合快速搭建原型
- Bokeh:原生支持交互式图表,自定义程度高,可灵活控制联动逻辑和图表样式
- Panel:支持多种可视化库(Matplotlib、Plotly、Bokeh等),组件化设计,适合构建复杂的交互式分析界面
内容的提问来源于stack exchange,提问作者Brie MerryWeather
相关产品推荐
相关产品推荐

