0

Basic needs: plot a map, and update accoding to variable. Challenges:

  • have to use rasterize, aggregation by datashade (big data)
  • holoviews .DynamicMap seems like not support rasterize.
import holoviews as hv, datashader as ds, geoviews as gv, geoviews.tile_sources as gvts
from holoviews.operation.datashader import datashade, rasterize, dynspread
import panel as pn

hv.extension('bokeh')
opts = dict(width=700, height=500, tools=['hover'], 
            colorbar=True,symmetric=True,clim=(-5,5),
            cmap='Spectral')
tiles = gvts.OSM.options(alpha=0.6)

def load_dh(var=None):
    points = gv.Points(df, kdims=['longitude','latitude'])
    return rasterize(points, x_sampling=0.01, y_sampling=0.01, aggregator=ds.mean(var)).options(**opts)* tiles

def on_var_select(event):
    var = event.obj.value
    col[-1] = load_dh(var=var)

var_select = pn.widgets.Select(name='var:', options=['dh_after_dtm10', '2', '3'])

var_select.param.watch(on_var_select, parameter_names=['value'])

col = pn.Column(var_select, load_dh(var_select.value))
col

The plot did show, but not update with changing variables:

images


I also try DynamicMap, which is not compataible with rasterize](Panel/Hvplot interaction when variable is changing):

Exception: Nesting a DynamicMap inside a DynamicMap is not supported.
ZHIHAO
  • 3
  • 1
  • UPDATE. The issues originate from vscode. https://discourse.holoviz.org/t/dynamicmap-and-holomap-responsiveness-when-running-out-of-a-vscode-notebook/2497/3 and https://github.com/holoviz/holoviews/pull/5398 solves the problem. – ZHIHAO Nov 25 '22 at 13:01

1 Answers1

0

The original code isn't runnable (try to show a fully reproducible example!), but when I made it runnable and removed GeoViews (not in my current envt), it seems to work:

import holoviews as hv, datashader as ds, panel as pn, pandas as pd
from holoviews.operation.datashader import datashade, rasterize, dynspread

df = pd.DataFrame(dict(longitude=[70,80,90,100], latitude=[10,30,20,5],
                       c1=[1,0,9,7], c2=[5,2,0,1], c3=[3,1,3,8]))

hv.extension('bokeh')
opts = dict(width=700, height=500, tools=['hover'], 
            colorbar=True,symmetric=True,clim=(-5,5),
            cmap='Spectral')

def load_dh(var=None):
    points = hv.Points(df, kdims=['longitude','latitude'])
    return dynspread(rasterize(points, x_sampling=0.01, y_sampling=0.01, aggregator=ds.mean(var))).options(**opts)

def on_var_select(event):
    var = event.obj.value
    col[-1] = load_dh(var=var)

var_select = pn.widgets.Select(name='var:', options=['c1', 'c2', 'c3'])

var_select.param.watch(on_var_select, parameter_names=['value'])

col = pn.Column(var_select, load_dh(var_select.value))
col

Screenshot1

That said, it seems like an overly complex solution, when pn.bind can be used very straightforwardly for this:

import holoviews as hv, datashader as ds, panel as pn, pandas as pd
from holoviews.operation.datashader import datashade, rasterize, dynspread

df = pd.DataFrame(dict(longitude=[70,80,90,100], latitude=[10,30,20,5],
                       c1=[1,0,9,7], c2=[5,2,0,1], c3=[3,1,3,8]))

hv.extension('bokeh')
opts = dict(width=700, height=500, tools=['hover'], 
            colorbar=True,symmetric=True,clim=(-5,5),
            cmap='Spectral')

def load_dh(var=None):
    points = hv.Points(df, kdims=['longitude','latitude'])
    return dynspread(rasterize(points, x_sampling=0.01, y_sampling=0.01, aggregator=ds.mean(var))).options(**opts)

var_select = pn.widgets.Select(name='var:', options=['c1', 'c2', 'c3'])

col = pn.Column(var_select, pn.bind(load_dh, var=var_select))
col

Screenshot2

Also, it's not so much that DynamicMap doesn't support rasterize as that the result of rasterize is already a DynamicMap, and only a single level of DynamicMap-ping is supported. It's always possible to make a single-level DynamicMap that does what you want, but because HoloViews operations (unlike DynamicMaps) do accept a DynamicMap as an argument, all you usually need to do is to call rasterize on your DynamicMap. So if you want to make a DynamicMap, just do so, then rasterize it.

James A. Bednar
  • 3,195
  • 1
  • 9
  • 13
  • 1
    Thank you for your answer. I think I figure it out as well. I am using VS Code, which does [not update the plot](https://stackoverflow.com/questions/64331613/holoviews-charts-not-updating-on-widget-selection). As for dynamicmap, thanks again for your well explanation! – ZHIHAO Oct 30 '22 at 13:08
  • That explains why it works for me! Glad to hear it is resolved. – James A. Bednar Oct 31 '22 at 23:55