Callback function to use 2 Dropdown Button that affect the same plot

I have 2 buttons (buttons and buttons_bank) that affect the same scatter. The first button affect the ‘i’ and the second the ‘j’ in : ((np.swapaxes(AllData[j, :, :, :], 1, 2))[i, :, :])

The problem is when I clic on a dropdown button, it will set the other variable (i or j) at 0.

I think that I can solve it using a callback function right ? It’s the first time that I use it and I don’t really know how to do it…

I suggest to create a Callback function and call it at the end of my code in : fig.show(CallBackFct) ?

Thank you for helping :smiley:

# Set all the Data in ALlData matrix
    AllData = np.zeros((NbreOfBanks, NbreMeasure, NbreOfSamples, NbreOfNozzles))
    for i in range(NbreMeasure):
        AllData[:, i, :, :] = load_json(FolderPath, files[FirstToSee + i], "Sensing")

    # Create the figure
    fig = go.Figure(go.Scatter(x=list(range(0, NbreOfSamples)), y=((np.swapaxes(AllData[0, :, :, :], 1, 2))[0, 0, :]),
                               mode="lines"))

    for k in range(1, NbreOfNozzles):
        fig.add_scatter(x=list(range(0, NbreOfSamples)), y=((np.swapaxes(AllData[0, :, :, :], 1, 2))[NbreSelect, k, :]),
                        mode="lines")

    fig.update_layout(width=1600, height=900, title="Sensing Measure", title_x=0.5,
                      xaxis_title="Measure number", yaxis_title="ADC Value")


    # Create button for selected JSON
    buttons = []
    for i in range(NbreMeasure):
        buttons.append(dict(method='update',
                            label=files[FirstToSee + i],
                            visible=True,
                            args=[{'y': ((np.swapaxes(AllData[Save_j, :, :, :], 1, 2))[i, :, :]),
                                   'x': list(range(0, NbreOfSamples)),
                                   'type': 'scatter'}]
                            )
                       )

    # Create button for each bank option
    buttons_bank = []
    BankName = ['BankA', 'BankB', 'BankC', 'BankD']
    for j in range(NbreOfBanks):
        buttons_bank.append(dict(method='update',
                                 label=str(BankName[j]),
                                 visible=True,
                                 args=[{'y': ((np.swapaxes(AllData[j, :, :, :], 1, 2))[Save_i, :, :]),
                                        'x': list(range(0, NbreOfSamples)),
                                        'type': 'scatter'}]
                                 )
                            )

    # Add the dropdown button to the layout
    fig.update_layout(
        updatemenus=[
            dict(
                buttons=buttons,
                direction='down',
                showactive=True,
                x=0.1,
                xanchor='left',
                y=1.1,
                yanchor='top'
            ),
            dict(
                buttons=buttons_bank,
                direction='down',
                showactive=True,
                x=0,
                xanchor='left',
                y=1.1,
                yanchor='top'
            )
        ])
    # add dropdown menus to the figure
    fig.update_layout(showlegend=True)
    fig.show()

From the way you phrase your question, it seems that you are currently not using callbacks, did I understand that correct? In that case, are you directly plotting a graph instead of creating a dashboard?

Although I am not familiar with your setup of adding buttons to fig.update_layout, this is how I would put that functionality in a callback:

from dash import callback, Output, Input, ctx

from components import list_of_button_components

layout = html.Div([dcc.Graph(id="my_graph"), *[button for button in list_of_button_components])

@callback(
    Output("my_graph", "figure",
    *[Input(button.id, "n_clicks") for button in list_of_button_components]
)
def update_graph(*button_values):
    // get id of component that triggered the callback
    triggered_component = ctx.triggered_id
    // Implement logic where you do something based on which button fired the callback
    // Since button_values is a list of values, you need to add logic to map the list of inputs 
    // to the correct button.

    // Based on the input values, now create or update your graph, so:
    fig = go.Figure(go.Scatter(x=list(range(0, NbreOfSamples)), 
                               y=((np.swapaxes(AllData[0, :, :, :], 1, 2))[0, 0, :]),
                               mode="lines"))
    // and further logic adapting the graph depending on the inputs