High refresh rate data not showing in the dashboard although `extendData` attribute has data!

I don’t see any plot with a high refresh rate streaming data. The refresh rate can go to a few miliseconds.

I’m following the techniques like clientside_callback from an earlier Plotly community discussion: Streaming sensor data at >100 points per second - #3 by davidparks21

I just see an empty graph on the dashboard, even though I can confirm the extendData attribute receives the data (y) as can be seen from below callback function
Bug

This might be related but I see the following JS error when inspecting the graph
js-error

Below is the code:

from collections import deque

import dash_bootstrap_components as dbc

from dash import Dash, dcc, html
from dash.dependencies import Input, Output, State


external_stylesheets = [
    dbc.themes.CERULEAN,
    {
        "href": "https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap",
        "rel": "stylesheet",
    },
]
app = Dash(__name__, external_stylesheets=external_stylesheets)
custom_styles = {
    # "background-color": "#f5f5f5",  # Light gray background color
    "font-family": "Roboto, sans-serif",  # Use Roboto font
    "padding": "2rem",  # Add some padding around the content
}

app.layout = dbc.Container(
    [
        html.H1("Real-Time Dashboard", className="text-center mb-4"),
        dbc.Row(
            [
                dbc.Col(
                    [
                        dcc.Graph(
                            id="live-data-graph",
                            figure={
                                "data": [
                                    {
                                        "x": [],
                                        "y": [],
                                        "mode": "lines",
                                        "type": "scattergl",
                                    }
                                ],
                                "layout": {
                                    "yaxis": {"fixedrange": False},
                                },
                            },
                            config={
                                "displayModeBar": False,
                                "staticPlot": False,
                            },
                        ),
                        dcc.Interval(id="interval-component", interval=100, n_intervals=0),
                        dcc.Store(id="data-fetch-store", data={}),
                        dcc.Store(id="graph-data-store", data=0),
                    ],
                    width=8,
                ),
            ],
            justify="center",
        ),
    ],
    fluid=True,
    style=custom_styles,
)

data_cache = deque(maxlen=100_000)

# some internal code to update `data_cache` based on incoming data 


@app.callback(Output("data-fetch-store", "data"), [Input("interval-component", "n_intervals")])
def fetch_data(n):
    store_data = list(data_cache)
    data_cache.clear()
    return store_data


@app.callback(Output("graph-data-store", "data"), [Input("data-fetch-store", "data")])
def move_data(data):
    return data


app.clientside_callback(
    """
    function (n_intervals, data) {
        if (data.length > 0) {
            const trace = {
                x: Array.from(Array(data.length).keys()),
                y: data,
                type: 'scattergl',
                mode: 'lines'
            };
            return [{ 'data': [trace], 'traces': [0] }];
        }
        return [];
    }
    """,
    [Output("live-data-graph", "extendData")],
    [Input("interval-component", "n_intervals")],
    [State("graph-data-store", "data")],
)

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

Any idea what could be the issue?

Hello @ealizadeh,

I’d probably recommend changing this, to this:

app.clientside_callback(
"""(data) => return data""",
Output("graph-data-store", "data"), [Input("data-fetch-store", "data")])

app.clientside_callback(
    """
    function (data) {
        if (data.length > 0) {
            const trace = {
                x: Array.from(Array(data.length).keys()),
                y: data,
                type: 'scattergl',
                mode: 'lines'
            };
            return [{ 'data': [trace], 'traces': [0] }];
        }
        return [];
    }
    """,
    [Output("live-data-graph", "extendData")],
    [Input("graph-data-store", "data")],
)

See if that makes a difference.

1 Like

@jinnyzor Thanks for the suggestion. The issue persists.

The issue was from the return data format. Having the return data in { "x": [data.x], "y": [data.y] } resolved it.

1 Like