Usage of Plotly.relayout function in Dash

Dear all,

I’m trying to update a line shape of figure (dcc.Graph) directly with javascript. My idea is to incorporate this Plotly.relayout function into clientside callback. I have an example below (normal clientside callkback is in blocked comment).
However, there is an error (Cannot read properties of undefined (reading ‘_guiEditing’))
What would be the issue and how to use the Plotly.relayout function normally in Dash?


import dash
from dash import Input, Output, State, dcc, html
import plotly.graph_objects as go
from numpy import random

app = dash.Dash(__name__)

x = [1, 2, 3, 4, 5]
y = random.randint(20, size=5)

fig = go.Figure()
fig.add_trace(go.Scatter(x=x, y=y, mode="lines+markers"))
fig.layout.shapes = [
        "visible": True,
        "x0": 2,
        "x1": 2,
        "yref": "paper",
        "y0": 0,
        "y1": 1,
        "type": "line",

app.layout = html.Div(
        dcc.Graph(id="main_figure", figure=fig),
            html.Button("Display Spike Line", id="line_shape", n_clicks=0),
            style={"display": "flex", "justify-content": "center"}

    function(n_clicks, fig) {
        var graphDiv = document.getElementById("main_figure");
        update_shape = {shapes: [{"visible": true}]};
        if (n_clicks % 2 === 0) {
            update_shape = {shapes: [{"visible": false}]};
        Plotly.relayout(graphDiv, update_shape)
        return figure;
    Output("main_figure", "figure"),
    Input("line_shape", "n_clicks"),
    State("main_figure", "figure"),

# app.clientside_callback(
#     """
#     function(n_clicks, fig) {
#         var figure = JSON.parse(JSON.stringify(fig));
#         if (n_clicks % 2 === 0) {
#             figure.layout.shapes[0]["visible"] = false;
#             return figure;
#         }
#         figure.layout.shapes[0]["visible"] = true;
#         return figure;
#     }
#     """,
#     Output("main_figure", "figure"),
#     Input("line_shape", "n_clicks"),
#     State("main_figure", "figure"),
# )

if __name__ == "__main__":

I think I have a similar problem:
I use Plotly.relayout to sync the zoom of multiple plots. It works in pure Plotly, but not with Dash. Not even changing the title works there. Do I have to do something differently when using Dash?

Here’s a screenshot of me playing with that in the browser JS console:

I get the same results when trying in this in any Plotly or Dash demo apps: works in Plotly, doesn’t in Dash.

Any idea?

Indeed, this is something uncovered.
There is another question of using Plotly.restyle (below) but hasn’t addressed yet. Perhaps, we need expert here…