Hello amazing Plotly community,
I have high refresh data (~100ms). I’m using a combination of the app.clientside_callback
and extendData
attribute to plot high refresh rate incoming data.
However, due to high amount of data, the graph gets very slow quickly. So, I just want to plot the last n seconds (e.g. last 10 seconds) of the data.
I’m not sure if this is possible with the extendData
attribute or not.
Any suggestions here?
data_cache = [deque(maxlen=7_500) for _ in range(2)] # the incoming data fills data_cache
def fetch_data(signal_index):
cache_copy = list(data_cache[signal_index])
data_cache[signal_index].clear()
return [(datetime.fromtimestamp(t), v) for t, v in cache_copy]
app = Dash(__name__, update_title=None)
app.layout = dbc.Container(
[
dcc.Interval(id="fetch-interval", interval=250, n_intervals=0),
dcc.Interval(id="graph-interval", interval=15, n_intervals=0),
dbc.Row(
[
dbc.Col(
[
dcc.Graph(
id="live-graph-ecg-ii",
figure={
"data": [
{
"x": [],
"y": [],
"mode": "lines",
"type": "scattergl",
"name": "ECG_II",
},
],
"layout": {
"xaxis": {
# "range": [0, 15],
},
"yaxis": {"title": "Plot 1"},
},
},
),
dcc.Store(id="data-fetch-store-1", data=[]),
],
width=8,
),
],
justify="center",
),
dbc.Row(
[
dbc.Col(
[
dcc.Graph(
id="live-graph-2",
figure={
"data": [
{
"x": [],
"y": [],
"mode": "lines",
"type": "scattergl",
"name": "Plot 2",
},
],
"layout": {
"yaxis": {"title": "Plot 2"},
},
},
),
dcc.Store(id="data-fetch-store-2", data=[]),
],
width=8,
),
],
justify="center",
),
],
fluid=True,
)
@app.callback(Output("data-fetch-store-1", "data"), [Input("fetch-interval", "n_intervals")])
def fetch_data_1(_):
return fetch_data(0)
@app.callback(Output("data-fetch-store-2", "data"), [Input("fetch-interval", "n_intervals")])
def fetch_data_2(_):
return fetch_data(1)
update_graph_js = """
function updateGraph (n_intervals, data) {
if (data && Array.isArray(data) && data.length > 0) {
var x = data.map(d => d[0]);
var y = data.map(d => d[1]);
return { "x": [[...x, null]], "y": [[...y, null]] };
}
return window.dash_clientside.no_update;
}
"""
app.clientside_callback(
update_graph_js,
Output("live-graph-1", "extendData"),
[Input("graph-interval", "n_intervals")],
[State("data-fetch-store-1", "data")],
)
app.clientside_callback(
update_graph_js,
Output("live-graph-2", "extendData"),
[Input("graph-interval", "n_intervals")],
[State("data-fetch-store-2", "data")],
)
if __name__ == "__main__":
app.run_server(debug=True)