Hi, a short question, with hopefully an easy answer:
Similar to the Bokeh question I would really like to set the active selection (~ box_select) in a Holoviews figure.
Is there a way to overwrite the selection?
I can think of a way by setting: streams.Selection1D.index = myindex, but this value cannot be modified.
ps: I failed to get the bokeh solution to work and I cant help but think there could be an better way in Holoview.
Also stuck on this; it seems like using “.event” on a Selection1D object does clear (or set) the index parameter on that stream, but the change does not get reflected to the plot. Here’s a quick test example I adapted from the scatter demo:
import numpy as np
import holoviews as hv
from holoviews import dim
from holoviews import streams
import panel as pn
hv.extension('bokeh')
np.random.seed(42)
coords = [(i, np.random.random()) for i in range(20)]
scatter = hv.Scatter(coords).opts(tools=['lasso_select'])
sel = streams.Selection1D(source=scatter)
def clear_sel(event):
print(f"old index was: {sel.index}")
sel.event(index=[])
print(f"new index is: {sel.index}")
def set_sel(event):
print(f"old index was: {sel.index}")
sel.event(index=[1,2,3])
print(f"new index is: {sel.index}")
plt = scatter.opts(color='k', marker='x', size=10)
clr_btn = pn.widgets.Button(name='Clear Selection', button_type='primary')
clr_btn.on_click(callback = lambda event: clear_sel(event=event))
set_btn = pn.widgets.Button(name='Set Selection', button_type='primary')
set_btn.on_click(callback = lambda event: set_sel(event=event))
layout = pn.Row(plt,pn.Column(clr_btn,set_btn))
layout
Maybe there’s some attribute on the upstream holoviews object (scatter in this case?) that needs to be targeted instead of the stream? Anyone have ideas here?
With the addition of a DynamicMap, I was able to get your code working. I also added a reset handler so that it works as expected after making a box selection on the plot.
import numpy as np
import holoviews as hv
from holoviews import dim
from holoviews import streams
import panel as pn
import pandas as pd
hv.extension('bokeh')
np.random.seed(42)
coords = [(i, np.random.random()) for i in range(20)]
scatter = hv.Scatter(coords).opts(tools=['box_select'], active_tools=['box_select'])
sel = streams.Selection1D(source=scatter)
def clear_sel(event):
# print(f"old index was: {sel.index}")
sel.event(index=[])
# print(f"new index is: {sel.index}")
def set_sel(event):
# print(f"old index was: {sel.index}")
sel.event(index=[1,2,3])
# print(f"new index is: {sel.index}")
def select_points(index, resetting):
# print(f"select_points index: {index}")
selected = scatter.iloc[:]
if index:
selected = scatter.iloc[index]
else:
selected = scatter.opts(selected=[i for i in range(20)])
return selected
plt = hv.DynamicMap(select_points, streams=[sel, streams.PlotReset()]).opts(color='k', marker='x', size=10)
clr_btn = pn.widgets.Button(name='Clear Selection', button_type='primary')
clr_btn.on_click(callback = lambda event: clear_sel(event=event))
set_btn = pn.widgets.Button(name='Set Selection', button_type='primary')
set_btn.on_click(callback = lambda event: set_sel(event=event))
layout = pn.Row(plt,pn.Column(clr_btn,set_btn))
layout