import copy import dash from dash.dependencies import Input, Output, State import dash_core_components as dcc import dash_html_components as html import plotly.graph_objects as go # Configure app app = dash.Dash( __name__, meta_tags=[{'name': 'viewport', 'content': 'width=device_width'}] ) app.config.suppress_callback_exceptions = True # Make a placeholder for the original figure DUMMY_FIGURE = dcc.Graph( id='figure-0', figure=go.Figure({ "data": [{"type": "scatter", "x": [1, 2, 3], "y": [1, 3, 2]}], "layout": {"title": {"text": "A Scatter graph"}} }), ### This config + dcc.Loading = click error ### config=dict( displayModeBar=True, modeBarButtons=[['resetScale2d']] ) ) # Add a store for the original figure figure_store = dcc.Store(id='figure-store') app.layout = html.Div( [ # Placeholder for the dummy figure store html.Div(figure_store, id='figure-store-container', hidden=True), # Container for the start button html.Div( html.Button( "Start App", id='start-button', ), id='start-button-container' ), # Placeholder for the figures ### If you make dcc.Loading into html.Div, it works with the Graph config ### noqa dcc.Loading( id='figure-container', type='circle' ), # Placeholder for the duplicate button (hidden at first) html.Div( html.Button( "Duplicate", id='duplicate-button', ), hidden=True, id='duplicate-button-container' ) ] ) @app.callback( [Output('duplicate-button-container', 'hidden'), Output('figure-store', 'data')], [Input('start-button', 'n_clicks')] ) def show_divs(start_clicks): # If you clicked the button, unhide duplicate # and make the dummy figure if start_clicks and start_clicks > 0: state = False fig = DUMMY_FIGURE else: state = True fig = None return state, fig @app.callback( Output('figure-container', 'children'), [Input('duplicate-button', 'n_clicks'), Input('figure-store', 'data')], [State('figure-store', 'data'), State('figure-container', 'children')] ) def duplicate_fig(duplicate_clicks, new_fig, stored_fig, existing_figs): # If there are figures already on the page, grab them if existing_figs: new_children = existing_figs else: new_children = [] # You clicked the duplicate button if duplicate_clicks: if stored_fig: new_children.append(copy.deepcopy(stored_fig)) # The dummy figure was added to the screen elif new_fig: new_children.append(new_fig) # Set the IDs to be unique for i in range(len(new_children)): child = new_children[i] child_id = child['props']['id'] if not child_id.endswith(f"-{i}"): child['props']['id'] += f"-{i}" return new_children if __name__ == "__main__": app.run_server( debug=True, dev_tools_silence_routes_logging=True )