I wanted to ask if it was possible to fill a param.multiselect widget by using the selection on a plot ?
Is there a existing mechanism like an “on_selection(func)” event or something.
It will be great if I could link my plot to my widget, but just having the value and an event mechanism will be enough to do what I want.
This little app allows you to select points on a plot with a box_select and it reacts to this new selection by selecting the widget values (I’ve displayed their index).
import numpy as np
import panel as pn
import param
import holoviews as hv
hv.extension('bokeh')
class App(pn.viewable.Viewer):
points_selection = param.ListSelector(objects=list(range(10)))
def __init__(self, **params):
super().__init__(**params)
self.points = hv.Points(np.random.multivariate_normal((0, 0), [[1, 0.1], [0.1, 1]], (10,)))
sel = hv.streams.Selection1D(source=self.points)
sel.add_subscriber(self.update_points_selection)
def update_points_selection(self, index):
self.points_selection = index
def __panel__(self):
return pn.Row(
pn.widgets.MultiSelect.from_param(self.param.points_selection, sizing_mode='stretch_height'),
self.points.opts(tools=['box_select'], active_tools=['box_select'])
)
App()
It’s using a few things:
One of the linked streams offered by holoviews, here a Selection1D that reacts on its source plot. See the user guide on custom interactivity with bokeh plots. Streams have a add_subscriber method that allows you that add any callback that you want. I’ve used that to update the list of selected points.
The app is a subclass pn.viewable.Viewer and implements def __panel__(self). This is a nice way to create your own panel components. Here you’ll notice that the app itself is rendered as Panel dashboard in the notebook
pn.widgets.MultiSelect.from_param that will create a MultiSelect widget linked to the Parameter points_selection.