Pass arguments into update_figure function depending on values in level of chained callback

Hi all,

I have a series of chained callbacks that progressively filter options down to the last level of the chain, the value of which is then passed as an argument into the update_figure function that plots the graphs on the dashboard. However, I would like for the value of any level of the callback chain to be passed as the argument into update_figure if a specific value in the corresponding dropdown is chosen. For instance, in the code below, if the ‘pest_family’, ‘pest_genus’, or ‘pest_species’ values were to be selected from their dropdowns to be “not found”, I would want the values for ‘pest_order’, ‘pest_family’, or ‘pest_genus’, respectively, to be passed as an argument into update_figure. Is this possible? (The month and year arguments represent values passed from time sliders). Thanks for the help.

@app.callback(
    Output('pest_family', 'options'),
    Input('pest_order', 'value')
)
def set_pfam_options(selected_pord):
    return [{'label': i, 'value': i} for i in aphis['Pest family'].loc[aphis['Pest order'] == selected_pord].unique() if i == i]

@app.callback(
    Output('pest_genus', 'options'),
    Input('pest_family', 'value')
)
def set_pgen_options(selected_pfam):
    return [{'label': i, 'value': i} for i in aphis['Pest genus'].loc[aphis['Pest family'] == selected_pfam].unique() if i == i]

@app.callback(
    Output('pest_species', 'options'),
    Input('pest_genus', 'value')
)
def set_pspc_options(selected_pgen):
    return [{'label': i, 'value': i} for i in aphis['Pest species'].loc[aphis['Pest genus'] == selected_pgen].unique() if i == i]

@app.callback(
    Output('host_determination', 'options'),
    Input('pest_species', 'value')
)
def set_host_det(selected_pspc):
    return [{'label': i, 'value': i} for i in aphis['Inspected Host cleaned'].loc[aphis['Pest species'] == selected_pspc].unique() if i == i]

@app.callback(
    Output('choro_plot1', 'figure'),
    Output('bar_plot1', 'figure'),
    Input('month_slider', 'value'),
    Input('year_slider', 'value'),
    Input('pest_species', 'value'),
    Input('host_determination', 'value')
)
def update_figure(month, year, pspc, hspc):

    filtered_df = aphis.loc[(aphis['Inspected Host cleaned'].isin([hspc])) & 
                             (aphis['Pest species'].isin([pspc])) &
                             (aphis['Interception Date'].dt.year == year) & 
                             (aphis['Interception Date'].dt.month == month)]

It’s a bit difficult to visualize what you are doing (though I think you are just creating a bunch of dynamic dropdowns)… that said, I know you can do that through a dcc.Store, so you can write the value to a store and bring it in via the State.

So your first callback would have:
Output(‘pest_family’, ‘options’),
Output(‘pest_order-store’,‘data’)
Input(‘pest_order’, ‘value’)

So on your figure, you can add States like State(‘pest-order-store’,‘data’),State(‘pest-family’,‘data’) and bring all those in that way. There might be a way to combine these callbacks into a smaller set as well, but I know the state will work.

Hi bgivens33,

Thanks for the help. I’m not sure what you mean by dynamic dropdown. Do you mean that the options change in a given dropdown based on the value chosen in the prior dropdown (or chained callbacks as the basic callbacks fundamentals page (Part 2. Basic Callbacks | Dash for Python Documentation | Plotly) calls them? If so, yes, that’s exactly what I’m doing.

I’ve tried your suggestion but I get an error for every instance where I add a ‘-store’ callback output - like Output(‘pest_order-store’, ‘data’) in your message:

image

How would I incorporate the ‘pest_order-store’ id into my layout? It might be obvious but would you mind elaborating a bit more? Here’s the layout section of my code if it helps. Thanks.

app.layout = html.Div(
    [
        dbc.Row(
            [
                # side bar
                dbc.Col(
                    [
                        dbc.Row(
                            [        
                                dbc.Col(
                                    [
                                        dbc.Row([
                                            html.Div(
                                                [
                                                    html.Br(),
                                                    html.Label(
                                                        children = "Pest order", 
                                                        className = "menu-title"
                                                    ),
                                                    # indicator dropdown
                                                    dcc.Dropdown(
                                                        pest_order,
                                                        id = "pest_order",
                                                        value = "",
                                                        className = 'dropdown',
                                                        clearable = True
                                                    ),
                                                    html.Br(),
                                                    html.Label(
                                                        children = "Pest family", 
                                                        className = "menu-title"
                                                    ),
                                                    # indicator dropdown
                                                    dcc.Dropdown(
                                                        pest_family,
                                                        id = "pest_family",
                                                        value = "",
                                                        className = 'dropdown',
                                                        clearable = True,
                                                        # multi = True
                                                    ),
                                                    html.Br(),
                                                    html.Label(
                                                        children = "Pest genus", 
                                                        className = "menu-title"
                                                    ),
                                                    # indicator dropdown
                                                    dcc.Dropdown(
                                                        pest_genus,
                                                        id = "pest_genus",
                                                        value = "",
                                                        className = 'dropdown',
                                                        clearable = True
                                                    ),
                                                    html.Br(),
                                                    html.Label(
                                                        children = "Pest species", 
                                                        className = "menu-title"
                                                    ),
                                                    # indicator dropdown
                                                    dcc.Dropdown(
                                                        pest_species,
                                                        id = "pest_species",
                                                        value = "",
                                                        className = 'dropdown',
                                                        clearable = True,
                                                        # multi = True
                                                    ),
                                                ]
                                            ),
                                        ])
                                    ], id = "pest_dropdowns",
                                ),    
                                dbc.Col(
                                    [
                                        dbc.Row([
                                            html.Div(
                                                [
                                                    html.Br(),
                                                    html.Label(
                                                        children = "Host Determination",
                                                        className = "menu-title"
                                                    ),
                                                    # indicator dropdown
                                                    dcc.Dropdown(
                                                        host_determination,
                                                        id = "host_determination",
                                                        value = "Solanum melongena",
                                                        className = 'dropdown',
                                                        clearable=True,
                                                        # multi = True
                                                    ),
                                                ]
                                            )
                                        ]),
                                        dbc.Row(
                                            [
                                                dbc.Col(
                                                    dbc.Row([
                                                        html.Div(
                                                            [
                                                                html.Br(),
                                                                html.Div(
                                                                children = "Year", 
                                                                className = "menu-title"
                                                                ),
                                                                # year slider
                                                                dcc.Slider(
                                                                min = aphis['Interception Date'].min().year,
                                                                max = aphis['Interception Date'].max().year,
                                                                step = 1,
                                                                value = 1997,
                                                                vertical=True,
                                                                marks = {1916: '1916', 
                                                                        1920: '1920',
                                                                        1930: '1930',
                                                                        1940: '1940', 
                                                                        1950: '1950',
                                                                        1960: '1960',
                                                                        1970: '1970',
                                                                        1980: '1980',
                                                                        1990: '1990',
                                                                        2000: '2000',
                                                                        2010: '2010',
                                                                        2021: '2021',
                                                                },
                                                                #tooltip property shows value on hover
                                                                tooltip={"placement": "bottom"},
                                                                id='year_slider',
                                                                ),
                                                            ]
                                                        ),
                                                    ])
                                                ),
                                                dbc.Col(
                                                    dbc.Row([
                                                        html.Div(
                                                            [
                                                                html.Br(),
                                                                html.Div(
                                                                children = "Month", 
                                                                className = "menu-title"
                                                                ),    
                                                                # month slider
                                                                dcc.Slider(
                                                                min = 1,
                                                                max = 12,
                                                                step = 1,
                                                                value= 7,
                                                                #tooltip property shows value on hover
                                                                tooltip={"placement": "bottom"},
                                                                id='month_slider',
                                                                vertical = True
                                                                ),
                                                            ]
                                                        )
                                                    ])
                                                )
                                            ],id = "time_sliders"
                                        )
                                    ], id = "host_dropdowns",
                                )
                            ], id = "dropdowns",
                        )
                    ], id='left-container',
                ),
                # main body
                dbc.Col(
                    [
                        html.Div(
                            # choropleth container
                            [
                                # choropleth
                                dcc.Graph(
                                    id='choro_plot1',
                                    className = 'choropleth',
                                    config = {"displayModeBar": False},
                                )
                            ], id = 'choro',
                        ), 
                        html.Div(
                            # bar plot container
                            [
                                # bar plot
                                dcc.Graph(
                                    id='bar_plot1',
                                    className = 'bar_plot',
                                    config = {"displayModeBar": False},
                                )
                            ], id = "bar",
                        )
                    ], id = 'right-container'
                )
            ], 
        )
    ]
)

This is dumb, but it somehow didn’t occur to me that I could include both the ‘pest_genus’ and ‘pest_species’ values as arguments in the update figure function. This realization solved my problem. Thanks for the suggestion though, @bgivens33.