如何使用Python创建可自定义每页图表布局的多页Dash仪表盘
实现多页面独立自定义布局的修改方案
核心逻辑:你现有的路由回调框架已经可以直接支撑需求,只需要在render_page_content函数中,给每个路径返回由dbc.Row、dbc.Col组合搭建的自定义布局即可,Dash Bootstrap Components的栅格系统默认是12列,你可以按需分配宽度。
完整修改后代码示例
import dash from dash import dcc, html, Input, Output, callback import dash_bootstrap_components as dbc import plotly.express as px import pandas as pd # 示例数据,用来生成测试图表 df = pd.DataFrame({ "Fruit": ["苹果", "橙子", "香蕉", "苹果", "橙子", "香蕉"], "Amount": [4, 1, 2, 2, 4, 5], "City": ["北京", "北京", "北京", "上海", "上海", "上海"] }) app = dash.Dash(external_stylesheets=[dbc.themes.DARKLY]) # 原有样式不变 SIDEBAR_STYLE = { "position": "fixed", "top": 0, "left": 0, "bottom": 0, "width": "16rem", "padding": "2rem 1rem", "background-color": "black", } CONTENT_STYLE = { "margin-left": "18rem", "margin-right": "2rem", "padding": "2rem 1rem", } sidebar = html.Div( [ html.H2("Sidebar", className="display-4"), html.Hr(), html.P( "A simple sidebar layout with navigation links", className="lead" ), dbc.Nav( [ dbc.NavLink("Home", href="/", active="exact"), dbc.NavLink("Page 1", href="/page-1", active="exact"), dbc.NavLink("Page 2", href="/page-2", active="exact"), dbc.NavLink("Page 3", href="/page-3", active="exact"), ], vertical=True, pills=True, ), ], style=SIDEBAR_STYLE, ) content = html.Div(id="page-content", style=CONTENT_STYLE) header = html.H4( "Side Example.py", className="bg-primary text-white p-2 mb-2 text-center" ) app.layout = html.Div([dcc.Location(id="url"),sidebar,header,content]) @callback(Output("page-content", "children"),[Input("url", "pathname")]) def render_page_content(pathname): # 首页布局:顶部导航条 + 一行两列布局 if pathname == "/": # 示例图表1 fig1 = px.bar(df, x="Fruit", y="Amount", color="City", barmode="group", template="plotly_dark") # 示例图表2 fig2 = px.line(df, x="Fruit", y="Amount", color="City", template="plotly_dark") return [ dbc.NavbarSimple(children=[html.H2('Particular info for HOMEPAGE')],color="grey",dark=True), html.Br(), # 一行两列布局,各占6份宽度 dbc.Row([ dbc.Col(dcc.Graph(figure=fig1), width=6), dbc.Col(dcc.Graph(figure=fig2), width=6) ]) ] # Page1布局:顶部导航条 + 第一行占满12列,第二行分三列 elif pathname == "/page-1": fig3 = px.pie(df, values='Amount', names='Fruit', template="plotly_dark") fig4 = px.box(df, x="City", y="Amount", template="plotly_dark") fig5 = px.histogram(df, x="Amount", template="plotly_dark") fig6 = px.scatter(df, x="Fruit", y="Amount", color="City", template="plotly_dark") return [ dbc.NavbarSimple(children=[html.H2('Particular info for PAGE1')],color="grey",dark=True), html.Br(), # 第一行占满全宽 dbc.Row(dbc.Col(dcc.Graph(figure=fig3), width=12)), html.Br(), # 第二行分三列,各占4份宽度 dbc.Row([ dbc.Col(dcc.Graph(figure=fig4), width=4), dbc.Col(dcc.Graph(figure=fig5), width=4), dbc.Col(dcc.Graph(figure=fig6), width=4) ]) ] # Page2布局:顶部导航条 + 左窄右宽布局 elif pathname == "/page-2": fig7 = px.area(df, x="Fruit", y="Amount", color="City", template="plotly_dark") fig8 = px.funnel(df, x='Amount', y='Fruit', template="plotly_dark") return [ dbc.NavbarSimple(children=[html.H2('Particular info for PAGE2')],color="grey",dark=True), html.Br(), dbc.Row([ dbc.Col(dcc.Graph(figure=fig7), width=3), dbc.Col(dcc.Graph(figure=fig8), width=9) ]) ] # Page3你可以按自己需求自定义布局 elif pathname == "/page-3": return [ dbc.NavbarSimple(children=[html.H2('Particular info for PAGE3')],color="grey",dark=True), html.Br(), html.P("这里可以自定义你想要的任何行列组合布局") ] # 404页面不变 return dbc.Jumbotron( [ html.H1("404: Not found", className="text-danger"), html.Hr(), html.P(f"The pathname {pathname} was not recognised..."), ] ) if __name__ == "__main__": app.run_server(port=8001, debug=True)
关键调整说明
- 每个页面的布局完全独立,你可以在对应路径的返回逻辑里任意嵌套
dbc.Row和dbc.Col,通过width参数调整列宽,总宽度加起来不超过12即可 - 你可以在列中放入任何Dash组件,包括图表、筛选器、表格、文本等
- 如果需要每个页面有独立的回调,注意保证全局组件id不重复即可
内容的提问来源于stack exchange,提问作者python_starter
相关产品推荐
相关产品推荐

