我正在使用 Plotly Dash 中具有 multi pages 功能的应用程序,它使用此模式:
|
app.py
pages
|games_
*dashboard.py
channels_dashboard.py
videos_dashboard.py
该项目正在讨论 youtube 游戏分析(视频、频道、评论)数据,页面文件夹文件的每个文件都包含布局变量中的布局和一些也在变量中的回调这里是一些示例代码:
layout = html.Div(children= [
html.Center(children= html.H1(children= ["Analysis for specfic", html.Span(
" Games ", style= {"color": THEME_COLORS[1]}), "Videos"])),
dcc.Graph(id= "video_stats_per_game",
figure= video_stats_per_game.update_layout(width= 1240, height= 500),
style= {'position': 'absolute', 'border': f'2px solid {THEME_COLORS[0]}','left': '10px',
'display': 'inline-block'}),
html.Div(["Choose a game:",
dcc.Dropdown(GAMES, "Minecraft" ,id= "game_dropdown")],
style= {'top': '600px', 'position': 'absolute', 'display': 'inline-block',
'width': '1230px'}), #Bla bla bla
这是同一文件的回调变量:
callback_1 = [Output('duration_vs_view', 'figure'), # this `duration_vs_view` is a plot name.
[Input('game_dropdown', 'value')]]
def duration_vs_view(value): # Some unreadable code ...
callback_2 = [Output('stats_growth', 'figure'),
[Input('game_dropdown', 'value')]]
def stats_growth(value): # bla bla bla
callbacks = callback_1 + callback_2 + callback_3
现在我想做的是将回调实现到我的
app.py
page_container
中,这是app.py
的一些代码:
# --------------------Creating the main app----------------------
app = Dash(__name__, use_pages=True,
external_stylesheets= EXERNAL_STYLESHEETS)
app.layout = html.Div([
html.Center(html.H1([html.Span("Youtube",
style= {"color": THEME_COLORS[1]}), ' gaming analysis'])),
html.Button('Channels dashboard', id='channels_dashboard_button'),
html.Button('Games dashboard', id='games_dashboard_button'),
html.Center(html.Button('Videos dashboard', id='videos_dashboard_button',)),
html.Div(id='page-content', children=dash.page_container)])
# ---------------------------------------------------------------
@app.callback(Output('page-content', 'children'),
[Input('channels_dashboard_button', 'n_clicks'),
Input('games_dashboard_button', 'n_clicks'),
Input('videos_dashboard_button', 'n_clicks')])
def display_page(channels_clicks, games_clicks, videos_clicks):
if channels_clicks:
return (pages.channels_dashboard.layout,
pages.channels_dashboard.callbacks)
elif games_clicks:
return (pages.games_dashboard.layout,
pages.games_dashboard.callbacks) # ...
else:
return ''
当我单击任何将我引导到带有回调的仪表板的按钮时,plotly dash 应用程序返回
callback
错误,这是错误消息:
dash.exceptions.InvalidCallbackReturnValue: The callback for `<Output `page-content.children`>`
returned a value having type `tuple`
which is not JSON serializable.
The value in question is either the only value returned,
or is in the top level of the returned list,
我希望在没有多页面功能的情况下,我将获得与运行它们一样好的仪表板(我在单个变量的正常回调方式之前使用过)
如果你能通过告诉我另一种方式来帮助我,请这样做,比如使用指向每个仪表板或其他东西的链接,如果你对如何解决这个问题有任何想法,如果问题需要更多代码或屏幕截图,请也这样做也告诉我,提前致谢
如评论中所述,您得到的
InvalidCallbackReturnValue
异常是因为 return 语句如下:
return (pages.channels_dashboard.layout, pages.channels_dashboard.callbacks)
对于您的
Output
:Output('page-content', 'children')
有效的返回值可以是:
return pages.channels_dashboard.layout
但是你不能这样设置页面回调。
我认为你的
display_page
回调,布局和回调变量的传递都是不必要的。我认为它对破折号页面功能不利。
您可以自己在页面(.py 文件)中实现回调。
这是一个带有回调的简单页面示例:
# File: pages/page1.py
from dash import html, callback, Input, Output, register_page
register_page(__name__)
layout = html.Div([
html.Button(id="page1-input", children="Click me"),
html.Div(id="page1-output")
])
@callback(
Output("page1-output", "children"),
Input("page1-input", "n_clicks")
)
def update_city_selected(n_clicks):
return n_clicks
无需使用像
Input('channels_dashboard_button', 'n_clicks')
这样的输入来转到某个页面,您可以只使用链接,不需要回调:
dcc.Link("Link", href="/page1")
如果您需要链接看起来/像按钮一样,您可以将按钮包装在链接中。
例子
app.py
:
from dash import Dash, html, dcc
import dash
app = Dash(__name__, use_pages=True)
app.layout = html.Div([
html.Div(
[
html.Div(dcc.Link(f"{page['name']} - {page['path']}", href=page["relative_path"]))
for page in dash.page_registry.values()
]
),
dash.page_container
])
if __name__ == '__main__':
app.run_server(debug=True)