Hi,
Updating a chart with subplots is basically the same as updating a chart with multiple traces. From the documentation:
extendData
( list | dict ; optional): Data that should be appended to existing traces. Has the form[updateData, traceIndices, maxPoints]
, whereupdateData
is an object containing the data to extend,traceIndices
(optional) is an array of trace indices that should be extended, andmaxPoints
(optional) is either an integer defining the maximum number of points allowed or an object with key:value pairs matchingupdateData
In most cases, updateData
is basically a dictionary with the x
and y
coordinates of the new points. They should be a list of lists when updating multiple traces, where each inner list contains the new points for each respective trace.
If traceIndices
is not provided, then each list will be given in ascending order to the traces. As an example, if you want to update the 1st and 3rd traces only, extendData
should be:
extend_data = [
{
"x": [
[0, 1], # x coord, 1st trace
[10, 11, 12]
],
"y": [
[1.212, 2.212], # y coord, 1st trace
[100, 200, 300]
],
}, # this is updateData
[0, 2] # this are traceIndices, if missing, traces 0 and 1 would be updated
]
Note that the trace order in the Figure
object depends on the order that you added each trace to each subplot and in principle you can have multiple traces in a single subplot. Therefore it is a good idea to take a look in figure["data"]
and perhaps implement the update logic based on it.
Here’s an adaptation of an example I had for subplots:
from dash import Dash, dcc, html, Input, Output, State
import pandas as pd
import plotly.graph_objects as go
from plotly.subplots import make_subplots
app = Dash(__name__)
fig = make_subplots(cols=3, rows=1)
fig.add_scatter(
x = [1,2,3],
y = [100, 200, 150],
col=1,
row=1
)
fig.add_scatter(
x = [1,2,3],
y = [20, 10, 15],
col=2,
row=1
)
fig.add_scatter(
x = [1,2,3],
y = [20, 10, 15],
col=3,
row=1
)
app.layout = html.Div(
[
dcc.Interval(id="interval", interval=2000),
dcc.Graph(id="graph", figure=fig)
]
)
@app.callback(
Output("graph", "extendData"),
Input("interval", "n_intervals"),
State("graph", "figure")
)
def update(n_intervals, figure):
print(figure) # figure["data"] is where the traces are defined
return [
{
"x": [
[figure["data"][0]["x"][-1] + i for i in range(1, 3)],
[figure["data"][2]["x"][-1] + i for i in range(1, 3)]
],
"y": [
[figure["data"][0]["y"][-1] + i * 50 for i in range(1, 3)],
[figure["data"][2]["y"][-1] + i * 5 for i in range(1, 3)]
]
},
[0, 2],
10 # last 10 points will be kept in each trace
]
if __name__ == "__main__":
app.run_server(debug=True)
Hope that this helps!