hi @martin2097
We actually talked about that possibility, but we decided not to move forward with that for the time being, because the solution was not really straightforward. It would require modifying the rendered in a specific way which might cause other issues.
Thank you so much Dash team. Iām so proud of you guys.
Thanks for explanation. Nevertheless it is fantastic update and it will make dash life much easier!
I guess the gotcha associated with (n callbacks ā 1 output) can be updated?
Very hyped about duplicate callback outputs and partially update figures!! Thanks heaps
Good point, @rictuar . Thank you for the tip.
Patch() looks really nice! Makes data-related callbacks look a lot more neat.
Fantastic! The multiple output will make code much cleaner.
Regarding the partial updates, how would one update only a column of data in dash datable? The data is a list of dictionaries, that does not seem obvious to me
Thanks
hi @mc2pezwb
It depends what part of the column youād like to update.
If, for example, youād like to update the first cell in the first column, try to figure out how to do that within a list of dictionaries. Then, you could try to implement that with Patch().
Letās take the Iris dataset.
import plotly.express as px
import pandas as pd
df = px.data.iris()
dff = df.to_dict("records") # this is the data format accepted by the DataTable
dff[0].update({'sepal_length': 99.1}) # update first cell of column `sepal_length` to 99.1
print(dff) # print to see result
Once you confirmed your result, you can try to implement the same thing with Patch().
from dash import Dash, html, Input, Output, Patch, dash_table, no_update
import plotly.express as px
app = Dash(__name__)
df = px.data.iris()
# dff = df.to_dict("records") # this is the data format accepted by the DataTable
# dff[0].update({'sepal_length': 99.1}) # update first cell of column `sepal_length` to 99.1
# print(dff) # print to see result
# exit()
app.layout = html.Div(
[
html.Button("Update first cell of first row only once", id="add-data-rows"),
dash_table.DataTable(
data=df.to_dict("records"),
columns=[{"name": i, "id": i} for i in df.columns],
page_size=10,
id="df-table",
),
]
)
@app.callback(
Output("df-table", "data"),
Input("add-data-rows", "n_clicks"),
prevent_initial_call=True,
)
def add_data_to_fig(n_clicks):
if n_clicks == 1:
patched_table = Patch()
# Instead of `dff[0].update({'sepal_length': 99.1})`
patched_table[0].update({'sepal_length': 99.1})
return patched_table
else:
return no_update
if __name__ == "__main__":
app.run_server(debug=True)
Great, ok so basically, using iloc to get the list position. This is rather neat.
Thanks a lot for the quick answer !
I just wanted to ask to clarify:
If I have a certain output that is shared by multiple callbacks, all I have to do is just add āallow_duplicate=Trueā to only one of them?
Does it matter which callback is given the tag?
And also does adding that tag to one of the callback sets that output to ensure duplicates are allowed for all other and future callbacks using that same output?
hi @hypervalent
if you have two callbacks that have the same output component property, only one of them needs an allow_duplicate=True
with prevent_initial_call=True
.
But if you add more callbacks with the same output component property, you will need to add the allow_duplicate=True
and the prevent_initial_call=True
to those callbacks as well.
See how in the example below the first and third callbacks have allow_duplicate=True
. Try to remove that from the third callback and you will get an error.
from dash import Dash, Input, Output, html, dcc, Patch
import plotly.express as px
import plotly.graph_objects as go
app = Dash(__name__)
app.layout = html.Div([
html.Button('Draw Graph', id='draw-2'),
html.Button('Reset Graph', id='reset-2'),
html.Button('Change Title', id='title-2'),
dcc.Graph(id='duplicate-output-graph')
])
@app.callback(
Output('duplicate-output-graph', 'figure', allow_duplicate=True),
Input('draw-2', 'n_clicks'),
prevent_initial_call=True
)
def draw_graph(n_clicks):
df = px.data.iris()
return px.scatter(df, x=df.columns[0], y=df.columns[1])
@app.callback(
Output('duplicate-output-graph', 'figure'),
Input('reset-2', 'n_clicks'),
)
def reset_graph(input):
return go.Figure()
@app.callback(
Output('duplicate-output-graph', 'figure', allow_duplicate=True),
Input('title-2', 'n_clicks'),
prevent_initial_call=True
)
def draw_graph(n_clicks):
patched_figure = Patch()
if n_clicks % 2 != 0:
patched_figure['layout']['title'] = 'Title 1'
else:
patched_figure['layout']['title'] = 'Title 2'
return patched_figure
if __name__ == '__main__':
app.run_server(debug=True)
Hello @adamschroeder ! Thank you for the quick response!
Just to make sure then, in the case of, say, n callbacks with the same output. All callbacks except one of them (n-1 callbacks) require the allow_duplicate=True
?
And in the case of there being more than 2 callbacks with the same output, does it matter which callback does not get the allow_duplicate=True
? I know in your specific scenario itās because the second callback does not want prevent_initial_call=True
, but in the case where all of the callbacks need prevent_initial_call=True
, does it ultimately matter which one I remove the allow_duplicate tag?
Thank you!
There are so many cool new features in 2.9.2, I think this is my favorite release to date.
I just wanted to highlight a few posts with more great info on the new things now available.
(And be sure to update to 2.9.3 to get the patch with the minor bugs reported in 2.9.2)
Examples of multi-page app navigation without refreshing the page
Anyone making multi-page apps where you update the URL in a callback will this new feature! Super fast navigation without the annoying page refresh. See more information and examples in this post:
Geolocation 
When deploying an app with the the new dcc.Geolocation
be sure to be using HTTPS, else Geolocation will not be enabled.
Here is another demo app showing more features available. This one also uses geopy
to get the address (if the āInclude Addressā checkbox is selected). Try it out on a phone or some other device with GPS enabled. The accuracy is amazing
https://dccgeolocation.pythonanywhere.com/
Examples of partial update and allow duplicates
This post has some great examples from community members @AIMPED and @jinnyzor including examples with pattern matching callbacks.
hi @hypervalent ,
Just to make sure then, in the case of, say, n callbacks with the same output. All callbacks except one of them (n-1 callbacks) require the
allow_duplicate=True
?
That is correct. They will also need the prevent_initial_call=True
. Same output meaning the same component_id
as well as the same component_property
used.
Regarding your second question,
Does it matter which callback does not get the
allow_duplicate=True
?
I donāt think it matters that much, or at least I havenāt encountered a case where I it made a difference. If you encounter that case, let me know.
Thank you so much! That pretty much answers all my questions
I will let you know if I encounter such a case
A post was split to a new topic: Label Aliases wot working, plotly 5.14.1
This is an amazing release! So many great features
I see this is not fixed in 2.9.3, should we reopen a bug report?