我正在尝试创建两个链接图。当您单击
fig_overview
图中的某个点时,fig_detail
图应更改以显示该点的特定视图。
在我看来,我已经严格遵循了本教程。第一个图和初始虚拟图按预期显示。不幸的是,第二个数字没有更新。
代码在 Python 3.10.12、jupyterlab 4.1.8、dash 2.17.0 上的 WSL 中运行。
app = Dash('prrdash', external_stylesheets=[dbc.themes.SOLAR])
app.layout = html.Div(children=[
dcc.Graph(id='fig_overview', figure=fig_overview(data)),
dcc.Graph(id='fig_detail', figure=fig_detail(data, None))
])
@app.callback(
Output('fig_detail', 'figure'),
Input('fig_overview', 'clickData')
)
def select_project(clickData):
if clickData is not None:
task = clickData['points'][0]['customdata'][0]
fig = fig_detail(data, task)
return fig
app.run()
到目前为止我尝试过的:
task
提取逻辑:我可以在print(task)
内select_project()
并获得预期的结果。fig_detail()
:我什至可以在回调中执行fig.show()
并获得预期结果。mode
的 jupyter_mode
和 app.run()
。id
- 这表明我是多么困惑。不,改变名字并不会改变任何东西。div
中,并用全新的children
替换其dcc.Graph
确实可以按预期工作。但我真的很想了解为什么这种简化的方法失败了!您对接下来要尝试什么有什么建议吗?或者甚至只是关于如何调试的一点提示。
我没有完整的代码,所以我必须创建自己的版本。
我用
app.run(debug=True)
运行它来查看问题
首先(在浏览器中)它显示了我的问题
['custom']
问题似乎出在
select_project
返回的内容上。
如果没有
clickData
那么它(自动)运行 return None
fig
那么代码对我有用
def select_project(clickData):
if clickData is not None:
print(clickData)
task = clickData['points'][0]['customdata'][0]
fig = fig_detail(data, task)
else:
fig = fig_detail(data, None)
return fig # <-- it has to always return figure
直接在代码中包含随机数据的最小工作代码
from dash import Dash, dcc, html, Input, Output, callback
import plotly.express as px
import random
import pandas as pd
SIZE = 30
random.seed(0)
data = pd.DataFrame({
'x': range(SIZE),
'y': [random.randint(0,100) for _ in range(SIZE)],
'size': [random.randint(1,5) for _ in range(SIZE)],
'color': random.choices(['red', 'green', 'blue', 'black', 'white'], k=SIZE),
})
def fig_overview(data):
fig = px.scatter(data, x="x", y="y", size="size", color="color")
return fig
def fig_detail(data, task):
#print('task:', task)
if task:
point = task['x']
temp_data = data[point-1:point+2]
else:
temp_data = data
#print('temp_data:', temp_data)
fig = px.scatter(temp_data, x="x", y="y", size="size", color="color")
return fig
app = Dash(__name__)
app.layout = html.Div(children=[
dcc.Graph(id='fig_overview', figure=fig_overview(data)),
dcc.Graph(id='fig_detail', figure=fig_detail(data, None))
])
@app.callback(
Output('fig_detail', 'figure'),
Input('fig_overview', 'clickData')
)
def select_project(clickData):
if clickData is not None:
#print(clickData)
task = clickData['points'][0]#['customdata'][0]
fig = fig_detail(data, task)
else:
fig = fig_detail(data, None)
#return None # <--- if I use it then it stop working but it doesn't show error
return fig # <-- it has to always return figure
if __name__ == '__main__':
app.run(debug=True)