plotly-dash [Python] 中依赖下拉菜单的链式回调的 KeyError

KeyError on chained callback for dependent dropdowns in plotly-dash [Python]

我正在尝试根据列中的唯一值在 dash/plotly 中创建一个依赖下拉列表,具体取决于在第一个下拉列表中选择的内容。我创建了一个链式回调,并且在视觉上,图表正在正确更新并且下拉列表正在正确填充。但是,我的一个字段(Category,与下拉菜单无关,它只是为类别着色)收到一个 KeyError,经过大量修改后我仍然无法弄清楚是什么原因造成的.这是我的布局、回调和我在调试环境中遇到的错误:

    #Layout
    app.layout = html.Div(children=[
    
    dcc.Dropdown(id='select_game',
                 options=[
                     {"label": "Harry Potter and the Philosopher's Stone (HP1)", "value":"HP1"},
                     {"label": "Harry Potter and the Chamber of Secrets (HP2)", "value":"HP2"},
                     {"label": "Harry Potter and the Prisoner of Azkaban (HP3)", "value":"HP3"},
                     {"label": "Harry Potter and the Goblet of Fire (HP4)", "value":"HP4"}
                     ],
                 multi=False,
                 value="HP1",
                 clearable=False, className = 'dcc-compon'
        
        ),

    dcc.Dropdown(id='select_platform',
                 options=[],
                 multi=False,
                 clearable=False, className = 'dcc-compon'
        
        ),    
    html.Br(),
    dcc.Graph(id="wrprogvis", figure={}),
    
], style={'font-family':'bahnschrift'})

#Chained callback
@app.callback(
    Output('select_platform', 'options'),
    Input('select_game', 'value')
    )

def get_platforms(select_game):
    wrcombo_plts = wrcombo[wrcombo['Game']==select_game]
    return [{'label': i, 'value': i} for i in wrcombo_plts['Platform'].unique()]
    print(wrcombo_plts['Platform'].unique())

@app.callback(
    Output('select_platform', 'value'),
    Input('select_platform', 'options')
    )

def slct_platform(select_platform):
    return[k['value'] for k in select_platform][0]

@app.callback(
        Output(component_id='wrprogvis', component_property='figure'),
        [Input(component_id='select_game', component_property='value'),
         Input(component_id='select_platform', component_property='value')
         ]
       )

#Graph build
def update_graph(game_slct, plat_slct):
    
    wrcombo_ = wrcombo.copy()
    wrcombo_ = wrcombo_[wrcombo_['Game']==game_slct]
    wrcombo_ = wrcombo_[wrcombo_['Platform']==plat_slct]
    
    wrfig = px.line(wrcombo_, x='Date', y='Time', color='Category', custom_data=['Runner', 'Game', 'Notes'], height=600)
    wrfig.update_traces(
        mode="markers+lines", 
        hovertemplate='<b>%{customdata[0]}</b><br>Time: %{y|%H:%M:%S} <br>Achieved on: %{x|%e %b %Y} <br>Notes: %{customdata[2]}'
        )
    
    wrfig.update_layout(yaxis_tickformat='%H:%M', title_font={"family": "Bahnschrift"}, legend_font_family="Bahnschrift", legend_title_font_family="Bahnschrift")
    wrfig.update_xaxes(
            title_font = {"family": "Bahnschrift"},
            tickfont = {"family": "Bahnschrift"},
            showspikes=True
        )
    
    wrfig.update_yaxes(
            title_font = {"family": "Bahnschrift"},
            tickfont = {"family": "Bahnschrift"},
            showspikes=True,
    )

    return wrfig

错误:

KeyError: 'Category'
Traceback (most recent call last)

    File "HPWRprog.py", line 194, in update_graph

    wrfig = px.line(wrcombo_, x='Date', y='Time', color='Category', custom_data=['Runner', 'Game', 'Notes'], height=600)

    File "_chart_types.py", line 252, in line

    return make_figure(args=locals(), constructor=go.Scatter)

    File "_core.py", line 1889, in make_figure

    for val in sorted_group_values[m.grouper]:

    KeyError: 'Category'

Traceback (most recent call last):
  File "HPWRprog.py", line 194, in update_graph
    wrfig = px.line(wrcombo_, x='Date', y='Time', color='Category', custom_data=['Runner', 'Game', 'Notes'], height=600)
  File "_chart_types.py", line 252, in line
    return make_figure(args=locals(), constructor=go.Scatter)
  File "_core.py", line 1889, in make_figure
    for val in sorted_group_values[m.grouper]:
KeyError: 'Category'

提前感谢任何帮助!

编辑:回调图显示不需要的回调,我不希望在更新选项(即右侧的路径)之前触发图更新。有什么办法可以防止这种情况发生吗? callback graph

所以我有一个解决方法,我确信有更好的解决方案,但它按预期工作。我相信图形 update_graph 功能在游戏下拉列表更新后触发,但在选项更新之前触发,导致 wrcombo_ 上的过滤器产生空白 table。第二次回调后,随着平台更新,错误自行修复,table 可以正确过滤。引入检查 table 是否为空允许我决定是否刷新图表,如下所示:

def update_graph(game_slct, plat_slct):

wrcombo_ = wrcombo.copy()
wrcombo_ = wrcombo_[wrcombo_['Game']==game_slct]
wrcombo_ = wrcombo_[wrcombo_['Platform']==plat_slct]

if len(wrcombo_) != 0:
    print(wrcombo_)
    wrfig = px.line(wrcombo_, x='Date', y='Time', color='Category', custom_data=['Runner', 'Game', 'Notes', 'Category'], height=600)
    wrfig.update_traces(
        mode="markers+lines", 
        hovertemplate='<b>%{customdata[0]}</b><br>Time: %{y|%H:%M:%S} <br>Achieved on: %{x|%e %b %Y} <br>Notes: %{customdata[2]}'
        )

    return wrfig
else:
    return dash.no_update

正如我提到的,不确定这是最佳选择,因为我仍然必须先过滤 table - 所以如果有更好的方法,请告诉我。在第二个回调之前不需要触发第三个回调,因此禁用它可能是拼图缺失的部分。

您可以维护输入变量的状态并根据按钮点击触发图形回调。 https://dash.plotly.com/basic-callbacks 在 'Dash App with State'