'How can I create a Holoviews dynamic map in a Dash callback function

Holoviews helps me a lot for plotting heatmap upon a huge dataset. Let's assume I made a simple function to generate a dynamic map:

def gen_map(pd_df):
    points = hv.Points(df, [x, y])
    tiles = hv.Tiles().opts(mapboxstyle='dark', accesstoken=token)
    overlay = tiles * datashade(points)
    return overlay

I noticed that this overlay is a kind of DynamicMap instance. If I need to use this element in a Dash application, based on the doc, I should use to_dash function to transform this DynamicMap to a DashComponents instance (let's named it as components). Finally I just need to assign components.children to a html.Div element.

A simple script looks like

overlay = gen_map(df)
components = to_dash(dash_app, [overlay])

app.layout = html.Div([components.children])

This works well when I generate this components out of the app.callback fucntion. But if I tried to put such function in an app.callback function with some other conditions which provided by end users, the heatmap on the map is fixed. It can't zoom in to show more details with the map together.

The script structure looks like this:

app.layout([
    dcc.DatePickrRange(id='date-range', start_date=start_date, end_date=end_date),
    html.Button('GO', id='go-button', n_clicks=0),
    html.Div(id='for-fig')
])

@app.callback(
    Output('for-fig', 'children'),
    Input('go-buttion', 'n_clicks'),
    State('date-range', 'start_date'),
    State('date-range', 'end_date'),
)
def show_graph(n_clicks, start_date, end_date):
    # I need to use a callback to get a sub dataset
    dff = df.loc[(df.time > start_date) & (df.time < end_date)]

    # I found the grid would be fixed if I created a map in this callback function
    overlay = gen_map(dff)
    components = to_dash(dash_app, [overlay])
    return components.children

I found that if I referred a global components instance, it works well in the callback function, such as:

components = gen_map(df)

@app.callback(...)
def show_graph(...):
    global components
    ...
    return components.children

But this will show the whole dataset rather than a sub dataset based on some customized conditions.

May I know the correct way to generate a dynamic Holoviews map in a Dash callback function, please? Many thanks for your help!



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source