✊🏿 Black Lives Matter. Please consider donating to Black Girls Code today.
🐇 Announcing Dash VTK for 3d simulation graphics. Check out the March webinar.

Increasing running time callback updating colour heatmap

I made a callback function which depends on multiple dropdown menus and range sliders as input to produce one heatmap. Similar to this:

@app.callback(
dash.dependencies.Output(‘heat’, ‘figure’),
[dash.dependencies.Input(‘intermediate-value’, ‘data’),
dash.dependencies.Input(‘dropdown’, ‘value’),
dash.dependencies.Input(‘colour’, ‘value’),
dash.dependencies.Input(‘slider’, ‘value’),
dash.dependencies.Input(‘dropdown2’, ‘value’)])
def update_figure(value, dropdown, colour, slider, dropdown2):
do lots of computations based on all input except for colour
fig = go.Figure()
if colour is None:
fig.add_trace(go.Heatmap())
else:
fig.add_trace(go.Heatmap(colorscale=colour))
return fig

But the computing takes a lot of time. Is there a possibility that if the color option is chosen later on, to skip all the computation and only add the color scale to the heatmap? Because now every time I select another colour option, the entire computation is repeated which takes too long time.

How to make another new callback with only selected colour as the input value and the new figure as output which is the figure created in another callback function based on multiple other inputs?

This is a good question and it doesn’t always have a simple answer. In your case you might have success by putting the data that is to go into the Heatmap into a store and then have a client-side callback update the figure. Admittedly this breaks the ‘no Javascript required’ clause but the Javascript is simple.
Here’s an example where I generate some random data to put in a Heatmap and store it in a Store. Then the data is passed to the figure client-side, where we adjust the colorscale.

import dash
from dash.dependencies import Input, Output, State, ClientsideFunction
import dash_html_components as html
import dash_core_components as dcc
import numpy as np
import plotly.graph_objects as go

ARRAY_SIZE=10

colorscales=['Greys','YlGnBu','Greens','YlOrRd','Bluered','RdBu','Reds','Blues','Picnic','Rainbow','Portland','Jet','Hot','Blackbody','Earth','Electric','Viridis','Cividis']

app = dash.Dash(__name__)

app.layout = html.Div(
    id='main',
    children=[
        html.Button("Generate data",id='gen-data'),
        dcc.Graph(id="graph"),
        dcc.Dropdown(
            id='choose-colorscale',
            options=[
                {'label': c, 'value': c} for c in colorscales
            ],
            value=colorscales[0],
            clearable=False
        ),
        dcc.Store(id='data')
    ]
)

@app.callback(
    Output('data','data'),
    [Input('gen-data','n_clicks')])
def generate_data(gen_data_n_clicks):
    return np.random.standard_normal((ARRAY_SIZE,ARRAY_SIZE))

app.clientside_callback(
"""
function plot_store_data(store_data,choose_colorscale_value,old_fig) {
    let new_fig = {...old_fig};
    new_fig['data']=[
        {
            'type': 'heatmap',
            'z': store_data,
            'colorscale': choose_colorscale_value
        }
    ]
    console.log(new_fig);
    return new_fig;
}
""",
Output('graph','figure'),
[Input('data','data'),Input('choose-colorscale','value')],
[State('graph','figure')])

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