Dash Subplot TypeError: 'Patch' object is not callable

Hi @GaNick welcome to the forums.

You are on the right track. If you ant to use the Patch() you need to stick to the methods of it. With append you can add a trace.

Does your plot really have only one trace? If this was the case, you could do this:

import dash
from plotly.subplots import make_subplots
import plotly.graph_objects as go
from dash import Input, Output,Patch, callback, html, dcc
import numpy as np
import random

app = dash.Dash(__name__)
subplot = make_subplots(figure=None)  # Define Subplot

app.layout = html.Div([
        html.Button(
            "Update Sublot",
            id="update-trace"
        ),
        dcc.Graph(
            figure=subplot, 
            id="my-fig"
        ),
])


@callback(Output("my-fig", "figure"), Input("update-trace", "n_clicks"))
def my_callback(n_clicks):
    # Defining a new random trace
    v = np.arange(-3, 5.1, 0.1) # x-axis
    i = []
    for each in v:
        i.append(1e-3*(2*random.random() - 1)) # y-axis

    # Creating a Patch object
    patched_figure = Patch()
    patched_figure['data'].append(
        go.Scatter(x=v, y=i, mode="lines")
    )
    return patched_figure


if __name__ == "__main__":
    app.run(debug=True)

If you have “real” subplots, you can choose where to add the traces via the corresponding axis:

import dash
from plotly.subplots import make_subplots
import plotly.graph_objects as go
from dash import Input, Output, Patch, callback, html, dcc, State
import numpy as np
import json


app = dash.Dash(__name__)
fig = make_subplots(rows=1, cols=2)

fig.add_trace(
    go.Scatter(x=[1, 2, 3], y=[4, 5, 6]),
    row=1, col=1
)

fig.add_trace(
    go.Scatter(x=[10, 20, 30], y=[40, 50, 60]),
    row=1, col=2
)

app.layout = html.Div([
    html.Button(
        "Update Sublot",
        id="update-trace"
    ),
    dcc.Graph(
        figure=fig,
        id="my-fig"
    ),
])


@callback(
    Output("my-fig", "figure"),
    Input("update-trace", "n_clicks"),
    prevent_initial_call=True
)
def my_callback(_):
    # Defining a new random trace
    v = np.arange(4)  # x-axis
    i = np.random.randint(4, 7, size=v.shape[0])

    # Creating a Patch object
    patched_figure = Patch()
    patched_figure['data'].extend(
        [
            go.Scatter(x=v*10, y=i*10, mode="lines", xaxis="x2", yaxis="y2"),
            go.Scatter(x=v, y=i, mode="lines")
        ]
    )
    return patched_figure


if __name__ == "__main__":
    app.run(debug=True)

In this example it helps paying attention to the x-axis range to distinguish between the subplots. I used patch.extend() just for demonstration, you could obviously use append() too.

Peek 2024-05-15 21-50

mred patch subplots

1 Like