Hello,
I am working on an app that creates a new plot from a callback. I would like to dynamically assign a callback to that plot as well.
I’ve read and tried what is described here but I can’t get it to work.
In this example I am declaring the callbacks statically for the first two plots:
app = Dash()
.
.
.
@app.callback([Output('tabs', 'children')],[Input('button', 'n_clicks')])
def create_graph(n_clicks):
if(n_clicks is None):
#do nothing
else:
#create new dcc.Tab containing new dcc.Graph with id="plot"+str(n_clicks)
return #updated tabs children
@app.callback([Output('plot1', 'figure')],
[Input('plot1', 'relayoutData')])
def callback_function(input):
return do_something(input)
@app.callback([Output('plot2', 'figure')],
[Input('plot2', 'relayoutData')])
def callback_function(input):
return do_something(input)
Now this obviously works fine for the first two plots, but when I try to create those callbacks dynamically the callbacks are not triggered, as if they didn’t existed:
app = Dash()
.
.
.
@app.callback([Output('tabs', 'children')],[Input('button', 'n_clicks')])
def create_graph(n_clicks):
if(n_clicks is None):
#do nothing
else:
#create new dcc.Tab containing new dcc.Graph with id="plot"+str(n_clicks)
@app.callback([Output("plot"+str(n_clicks), 'figure')],
[Input("plot"+str(n_clicks), 'relayoutData')])
def callback_function(input):
return do_something(input)
return #updated tabs children
But when I try to mix both codes (declare them statically and dynamically), just for the sake of understanding what is going on then it tells me that I am creating a duplicate callback output:
Merged code:
app = Dash()
.
.
.
@app.callback([Output('tabs', 'children')],[Input('button', 'n_clicks')])
def create_graph(n_clicks):
if(n_clicks is None):
#do nothing
else:
#create new dcc.Tab containing new dcc.Graph with id="plot"+str(n_clicks)
@app.callback([Output("plot"+str(n_clicks), 'figure')],
[Input("plot"+str(n_clicks), 'relayoutData')])
def callback_function(input):
return do_something(input)
return #updated tabs children
@app.callback([Output('plot1', 'figure')],
[Input('plot1', 'relayoutData')])
def callback_function(input):
return do_something(input)
@app.callback([Output('plot2', 'figure')],
[Input('plot2', 'relayoutData')])
def callback_function(input):
return do_something(input)
Exception:
dash.exceptions.DuplicateCallbackOutput:
Multi output …plot1.figure… contains anOutput
object
that was already assigned.
Duplicates:
{‘plot1.figure’}
So what I get from this is that when I try to create them dynamically they do get created but are unresponsive.
How can I create them dynamically?