Plotly如何通过下拉菜单选择对应Pandas DataFrame生成4张子图
实现方案
可以实现,最简单的方案是预生成所有国家的图表轨迹,通过下拉菜单控制轨迹可见性,完全不需要依赖动态加载DataFrame的逻辑,也适配你现有的单DataFrame绘图代码。
核心逻辑
- 你原本的单国家4张子图的绘图代码不需要做修改,直接复用即可
- 提前遍历所有国家的DataFrame,把每个国家对应的4条绘图轨迹全部添加到同一个画布中,默认仅显示第一个国家的轨迹
- 下拉菜单的每个选项绑定「仅展示当前国家对应4条轨迹、隐藏其他所有轨迹」的交互规则
示例代码
import plotly.subplots as sp import plotly.graph_objects as go # 这是你原来写的单df生成4张子图轨迹的函数,直接复用即可 def get_country_traces(df): # 以下4条轨迹的类型、字段、样式完全和你之前单国家绘图逻辑保持一致 trace1 = go.Scatter(x=df['date'], y=df['value1'], name='指标1') # 对应子图1 trace2 = go.Bar(x=df['date'], y=df['value2'], name='指标2') # 对应子图2 trace3 = go.Line(x=df['date'], y=df['value3'], name='指标3') # 对应子图3 trace4 = go.Histogram(x=df['value4'], name='指标4') # 对应子图4 return [trace1, trace2, trace3, trace4] # 你的国家数据字典 dfs = {'Germany': germany_df, 'France': france_df, 'Italy': italy_df} # 初始化子图布局,和你原来的子图配置保持一致即可,这里示例为2行2列 fig = sp.make_subplots(rows=2, cols=2, subplot_titles=('子图1','子图2','子图3','子图4')) # 存储每个国家对应的轨迹索引,后续构造下拉菜单用 country_trace_index = {} current_idx = 0 for country, df in dfs.items(): traces = get_country_traces(df) # 把4条轨迹加到对应子图位置,和你原来的添加位置保持一致 fig.add_trace(traces[0], row=1, col=1) fig.add_trace(traces[1], row=1, col=2) fig.add_trace(traces[2], row=2, col=1) fig.add_trace(traces[3], row=2, col=2) # 记录当前国家对应的4个轨迹的索引 country_trace_index[country] = list(range(current_idx, current_idx+4)) current_idx +=4 # 默认仅第一个国家的轨迹可见 if country == list(dfs.keys())[0]: for i in country_trace_index[country]: fig.data[i].visible = True else: for i in country_trace_index[country]: fig.data[i].visible = False # 构造下拉菜单按钮 buttons = [] for country in dfs.keys(): visible_list = [False]*len(fig.data) for idx in country_trace_index[country]: visible_list[idx] = True buttons.append( dict( label=country, method='update', args=[{'visible': visible_list}, {'title': f'{country} 数据看板'}] # 可选,切换时更新标题 ) ) # 把下拉菜单加到画布布局里 fig.update_layout( updatemenus=[ dict( type='dropdown', buttons=buttons, direction='down', showactive=True, x=0.1, y=1.15 # 调整下拉菜单的位置,避免和标题/子图重叠 ) ], title_text=f'{list(dfs.keys())[0]} 数据看板' ) fig.show()
注意事项
- 如果你的国家数量超过20个或者单国家轨迹数量很多,可能会导致静态文件体积过大,这种情况才需要考虑用Dash做服务端动态渲染,普通场景下上述方案是最省成本的实现方式
- 子图的行列配置、轨迹类型完全和你之前单国家的绘图逻辑保持一致,不需要做额外调整
内容的提问来源于stack exchange,提问作者jsyemty
相关产品推荐
相关产品推荐

