如何将两个Plotly-Dash金融数据仪表盘合并为上下布局的单一仪表盘?
当然可以实现!我刚好有合并多个Dash应用的经验,下面就给你一步步拆解怎么把这两个仪表盘整合到同一个页面,实现上下排列的布局。
核心思路
合并的关键在于复用原有逻辑,统一应用实例:
- 把两个应用的依赖、数据定义合并到一起
- 将两个仪表盘的布局整合进同一个根容器,默认就是垂直上下排列
- 保留各自的回调函数(只要组件ID不重复,就不会互相干扰)
合并后的完整代码
# 统一导入依赖(去重合并) import pandas as pd import plotly.express as px import dash import dash_core_components as dcc import dash_html_components as html from dash.dependencies import Input, Output # 第一个仪表盘的数据 data = [['2020-01-31', 100, 100, 100], ['2020-02-28', 101, 107, 99], ['2020-03-31', 104, 109, 93], ['2020-04-30', 112, 115, 94], ['2020-05-31', 112, 120, 89]] df = pd.DataFrame(data, columns = ['DATE', 'A', 'B', 'C']) df = df.set_index('DATE') # 第二个仪表盘的数据 data2 = [['A', 'B', 0.4], ['A', 'C', 0.5], ['A', 'D', 0.1], ['X', 'Y', 0.15], ['X', 'Z', 0.85]] df2 = pd.DataFrame(data2, columns = ['BM_NAME', 'INDEX_NAME', 'WEIGHT']) # 创建单一的Dash应用实例 app = dash.Dash() # 合并后的布局:上下排列两个仪表盘模块 app.layout = html.Div(children=[ # 第一个仪表盘模块(加内边距优化视觉) html.Div([ html.H1(children='Index Dashboard'), html.P('''Pick one or more stocks from the dropdown below.'''), dcc.Dropdown( id='index-dropdown', options=[{'label': x, 'value': x} for x in df.columns], value='A', multi=True, clearable=True ), dcc.Graph(id='price-graph') ], style={'padding': '20px'}), # 第二个仪表盘模块(加内边距优化视觉) html.Div([ html.H1(children='BM Composition'), dcc.Dropdown( id='BM-dropdown', options=[{'label': x, 'value': x} for x in df2.BM_NAME.unique()], value='A', multi=False, clearable=True ), dcc.Graph(id='bar-chart') ], style={'padding': '20px'}) ]) # 保留第一个仪表盘的回调逻辑 @app.callback( Output(component_id='price-graph', component_property='figure'), [Input(component_id='index-dropdown', component_property='value')], ) def display_time_series(selected_index): dff = df[selected_index] fig = px.line(dff, x=df.index, y=selected_index, labels={'x': 'x axis label'}) fig.update_layout( title="Price Index Development", xaxis_title="Month", yaxis_title="Price", font=dict(size=13)) return fig # 保留第二个仪表盘的回调逻辑 @app.callback( Output(component_id="bar-chart", component_property="figure"), [Input(component_id="BM-dropdown", component_property="value")], ) def display_BM_composition(selected_BM): filtered_BM = df2[df2.BM_NAME == selected_BM] barchart = px.bar( data_frame=filtered_BM, x="BM_NAME", y="WEIGHT", color="INDEX_NAME", opacity=0.9, barmode='group') return barchart # 启动本地服务器 if __name__ == '__main__': app.run_server(debug=True, use_reloader=False)
关键细节说明
- 布局隔离:我给每个仪表盘外层加了独立的
html.Div和内边距,让两个模块视觉上更清晰,你也可以根据需求添加边框、背景色等样式。 - 回调独立性:两个回调函数绑定的组件ID完全不重复,所以各自的交互逻辑(下拉选框控制图表)不会互相干扰。
- 扩展性:如果后续需要更复杂的布局(比如左右分栏),可以引入
dash_bootstrap_components的栅格系统,但当前需求用默认的垂直流式布局就足够了。
内容的提问来源于stack exchange,提问作者Ben
相关产品推荐
相关产品推荐

