extendData for HeatMap

I´m writting a live app that loads a large amount of data into a Heatmap. Currently I´m using the same method as in the examples.

app = dash.Dash()

app.layout = html.Div([
    dcc.Graph(
        id='live-update-graph',
        figure=initial_fig
    ),
    dcc.Interval(
        id='interval-component',
        interval=1*100, # in milliseconds
        n_intervals=0
    )
])

@app.callback(Output('live-update-graph', 'extendData'),
              Input('interval-component', 'n_intervals'))
def update_plot(n_interval):
    #parse data and load into dataframe
    #create the heatmap
    fig = go.Figure(data=go.Heatmap(
            z=df.values,
            x=df.columns,
            y=df.index,
            type='heatmap',
    ))
    return fig

app.run_server(debug=True, use_reloader=False)

I’m trying to achieve a real time heat map plot. The issue is that when I run the code, it’ll only plot the initial plot and not add any data and visualize it. Does anyone know how I could achieve this?

Thanks

1 Like

Could you update figure instead of the extendData property?

Wouldn’t that require transferring all the data again?

I’ve been able to update now with figure. The issue with this is that I can’t add to an existing plot (to my knowledge as I’m new to Dash) which leaves me constantly reloading a larger dataframe through each iteration from a large data set.

Disclaimer: I’m new to Dash.

It was my understanding that extendData would allow me to append data to an existing plot. Am I wrong in thinking this?

No, that is correct :slight_smile:

1 Like

If the PlotlyJS graphing library supports updating heatmap data via extendTraces function call, then it should work with the extendData prop. This would be significantly faster than returning a new figure each interval.

@nqv also had a similar question in the recent past, which I just saw today. I haven’t looked in much detail; my primary use case remains scatter plot traces. I need to take a deeper look at heat maps.

Note: the extendData callback expects data to be formatted differently than with figure (or even figure.data). AFAIK you cannot use plotly.graph_objects with extendData

This keeps being an issue, go.Heatmap does not seem to be updated correctly when using Dash extendData.

Reproducible example:

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


heatmap = go.Heatmap(
    z=[[1, None, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20]],
    x=[1, 2, 3, 4, 5],
    y=['Morning', 'Afternoon', 'Evening'],
    hoverongaps = False
)
fig = go.Figure(heatmap)

app = dash.Dash(__name__, update_title=None)
app.layout = html.Div(
    [
        dcc.Graph(id='graph', figure=fig), 
        dcc.Interval(id="interval", interval=1000)
    ]
)


@app.callback(
    Output('graph', 'extendData'), 
    [Input('interval', 'n_intervals')],
    [State("graph", "figure")]
)
def update_data(n_intervals, fig):
    if n_intervals:
        print(f"iter: {n_intervals - 1}")
        print(fig["data"][0]["x"])
        print(fig["data"][0]["z"])
        print()
        return (
            dict(
                z=[[[1], [20], [300]]],
                x=[[5 + n_intervals]],
            ), 
            [0]
        )


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

This prints in the terminal:

iter: 0
[1, 2, 3, 4, 5]
[[1, None, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20]]

iter: 1
[1, 2, 3, 4, 5, 6]
[[1, None, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20], [1], [20], [300]]

iter: 2
[1, 2, 3, 4, 5, 6, 7]
[[1, None, 30, 50, 1], [20, 1, 60, 80, 30], [30, 60, 1, -10, 20], [1], [20], [300], [1], [20], [300]]

So, it x data gets correctly extended but not z data.
Is there any workaround for this that does not involve sending back and forth all the dataset (which would defeat the purpose)?