python/dash/plotly 更新图形不起作用

问题描述 投票:0回答:1

我正在尝试创建两个链接图。当您单击

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()

到目前为止我尝试过的:

  1. 验证
    task
    提取逻辑:我可以在
    print(task)
    select_project()
    并获得预期的结果。
  2. 验证绘图生成器
    fig_detail()
    :我什至可以在回调中执行
    fig.show()
    并获得预期结果。
  3. 改变
    mode
    jupyter_mode
    app.run()
  4. 改变布局。代码已经显示了 DOM 的精简版本。
  5. 改变
    id
    - 这表明我是多么困惑。不,改变名字并不会改变任何东西。
  6. do有一个解决方法:将图表包装在额外的
    div
    中,并用全新的
    children
    替换其
    dcc.Graph
    确实可以按预期工作。但我真的很想了解为什么这种简化的方法失败了!

您对接下来要尝试什么有什么建议吗?或者甚至只是关于如何调试的一点提示。

python plotly-dash
1个回答
0
投票

我没有完整的代码,所以我必须创建自己的版本。
我用

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)
© www.soinside.com 2019 - 2024. All rights reserved.