How to get figure object from dcc.Graph instead of dict

I need to update a figure on some event (button click in my example). This depends on the state of the figure that I want to update.
For this I’d need to return the full figure object from dcc.Graph instead of a dictionary (???).
Specifically I want to add traces to the figure
What I tried:

  • fig.add_trace(...). Doesn’t work since fig is a dict and not a figure object

  • fig['data'].append(...) since fig[‘data’] contains an immutable tuple and not a list

  • old = fig['data'], new=old + tuple([go.Scatter(...)]), fig['data'] = new Doesn’t work for reasons I don’t understand

minimal example to show what I mean:

import dash
import dash_core_components as dcc
import dash_html_components as html
import plotly.express as px
import pandas as pd
from dash.dependencies import Input, Output, State

external_stylesheets = ['https://codepen.io/chriddyp/pen/bWLwgP.css']
app = dash.Dash(__name__, external_stylesheets=external_stylesheets)
df = pd.read_csv('https://gist.githubusercontent.com/chriddyp/5d1ea79569ed194d432e56108a04d188/raw/a9f9e8076b837d541398e999dcbac2b2826a81f8/gdp-life-exp-2007.csv')


fig = px.scatter(df, x="gdp per capita", y="life expectancy",
                     size="population", color="continent", hover_name="country",
                     log_x=True, size_max=60)


app.layout = html.Div([
    dcc.Graph(id='graph', figure=fig),
    html.Button('click', id='button')])


@app.callback(Output('graph', 'figure'),
              Input('button', 'n_click'),
              State('graph', 'figure'))
def update_fig(button_pressed, fig):
    # stuff i want to do with fig:
    # fig.add_trace(...)
    # doesn't work
    return fig


if __name__ == '__main__':
    app.run_server(debug=True)

Hi @luggie

One way to do this is to add:

import plotly.graph_objects as go

Then in your callback start with:

fig=go.Figure(fig)

This will convert the dictionary to a figure object and you can update it using things like fig.add_trace()

And this is probably just a typo, but:

Input('button', 'n_click'),

should be:

Input('button', 'n_clicks'),

I hope this helps :slight_smile:

1 Like

Thanks! That was what I was looking for