Allowing users to edit graph properties without code changes

Hi community,

Recently I came across the editable property available in the config options of the figure object or dcc.Graph.

If you are not aware config can be passed to the and dcc.Graph function if using Dash. It allows us to control a bunch of cool chart configuration options.

Editable graphs in Plotly

  • editable (boolean; optional): We can edit titles, move annotations, etc - sets all pieces of edits unless a separate edits config item overrides individual parts.

As mentioned in the docs, this flag if set to True allows you to edit titles (both chart and axes), annotations text, legend items text, and move legend, color bar, and annotations in the graph.

Below is the complete list of possible edits:

  • annotationPosition
  • annotationTail
  • annotationText
  • axisTitleText
  • colorbarPosition
  • colorbarTitleText
  • legendPosition
  • legendText
  • shapePosition
  • titleText

We can choose to only allow selected of the above properties to be editable by passing edits in combination with the editable flag to the config dictionary.


import as px
df =

fig = px.histogram(
    df, x="sex", y="total_bill", color="smoker", barmode="group"
    x="Female", y=1000, text="Text annotation", showarrow=True, arrowhead=1

The user edits does not persist, which means the graph will reset on refresh.

Persisting user edits with Dash

In Dash we can store the modified figure by using dcc.Store to store the figure by listening to the relayoutData property of the graph via a callback.

By setting the storage_type = "session" of dcc.Store we can persist the data on page refresh.


from dash import Dash, html, dcc, callback, Input, State, Output
import as px
import plotly.graph_objects as go

# function to create graph
def generate_graph():
    df =
    fig = px.histogram(df, x="sex", y="total_bill", color="smoker", barmode="group")
        x="Female", y=1000, text="Text annotation", showarrow=True, arrowhead=1
    return fig

app = Dash(__name__)

app.layout = html.Div(
        dcc.Store(id="fig-store", storage_type="session"),

# This callback renders the chart
    Output("example-graph", "figure"),
    Input("fig-store", "data"),
def update(fig_data):
    if fig_data:
        fig = go.Figure(fig_data)
        fig = generate_graph()
    return fig

# This callback stores the current state of the figure after each edits in dcc store
    Output("fig-store", "data"),
    Input("example-graph", "relayoutData"),
    State("example-graph", "figure"),
def update(relayoutData, fig):
    return fig

if __name__ == "__main__":



HI @atharvakatre, thanks for the tip and sample code! This might be helpful in the future


Very useful! Thank you for sharing!

1 Like