基本需求:绘制一张地图,并根据编码更新为变量。挑战:
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情节确实显示了,但没有随变量的变化而更新:
我还尝试了DynamicMap,它与rasterize不兼容](变量变化时面板/图形交互):
Exception: Nesting a DynamicMap inside a DynamicMap is not supported.发布于 2022-10-30 02:22:56
原始代码不是可运行的(尝试显示一个完全可复制的示例!),但当我使其可运行并删除GeoViews (不在我当前的envt中)时,它似乎有效:
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

尽管如此,这似乎是一个过于复杂的解决方案,当pn.bind可以非常直接地用于此时:
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

而且,与其说DynamicMap不支持rasterize,不如说rasterize的结果已经是DynamicMap,并且只支持单一级别的DynamicMap。总是可以制作一个单级别的DynamicMap来实现您想做的事情,但是由于HoloViews操作(与DynamicMaps不同)确实接受DynamicMap作为参数,所以您通常需要做的就是调用DynamicMap上的rasterize。因此,如果您想要制作一个DynamicMap,只需这样做,然后rasterize它。
https://stackoverflow.com/questions/74229685
复制相似问题