It's not possible to have multiple callbacks/Output for same object(graph)?

I have a list of buttons that should individually update the same graph, and instead of writing them all as individual inputs to the same callback I have created a for loop to create the callbacks for each button, but i get the following error:

Multi output …ButtonGraph.figure… contains an Output object that was already assigned.

Duplicates: {‘ButtonGraph.figure’}

Is there any way to allow duplicates or do i have to create one callback with one ouput for all inputs for all buttons?

Example code:

def create_button_plot(df,button):
    fig = somefunc(df,button)
    return fig  

Button_list=[1,2,3,4,5,6,7,8,9,10,11,12,13]
   
for button in Button_list: 
    app.callback([Output('ButtonGraph','figure')],
            [Input('button_{}'.format(tool),'n_clicks')]
    )(create_button_plot(df,button)

Currently any component property can only be the output of a single callback, so you won’t be able to do what you’re trying to do.

You’ll have to write a single callback that takes all of the buttons as inputs. You can use dash.callback_context quite neatly to achieve this. Check out the question “How do I determine which Input has changed?” here in the docs.

3 Likes

Thank you for a quick reply, I solved it by looping the creation of Inputs instead, and checking the time stamp to only update the plot with the latest click. See example below:

Button_list=['hammer','saw'...]
input_list=[Input('button_{}'.format(tool),'n_clicks_timestamp') for tool in Button_list]

@app.callback(Output('Button_Graph','figure'),
                   input_list)
    def update_Matlab_plot(b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b13,b14,b15,b16,b17,b18,b19,b20,b21,b22):
        b_list=[b0,b1,b2,b3,b4,b5,b6,b7,b8,b9,b10,b11,b13,b14,b15,b16,b17,b18,b19,b20,b21,b22]
    
    try:
            INDEX=b_list.index(max(filter(lambda x: x is not None,b_list)))
            
            
            fig = create_Button_plot(df,Button_list[INDEX])
    except Exception as E:
            traces=[]
            traces.append(go.Scatter(
                         y=[],
                         x=[],
                         name= 'TEST'))
       
    fig = go.Figure(data=traces)