Hello, I’m learning how to use panel and param.
I’d like to understand what it the best way to handle a case like the following.
I have a parametrized object (Visualizer
) having members of type ItemPlot
(bokeh figures). One member is called item_plot
.
The plot is clickable and I’d like to change the Visualizer.item
param by interacting with the item_plot
member.
import param
import panel as pn
from bokeh.plotting import figure
from bokeh.models import ColumnDataSource, ResetTool, TapTool
data = {"x": [0, 1, 2, 3, 4], "y": [5, 6, 7, 8, 9]}
class Visualizer(param.Parameterized):
item = param.Integer(default=1, bounds=(1, 5))
def _update_itemplot_active_item(self, *events):
print(events)
for event in events:
if event.name == "item":
self.item_plot.active_item = event.new
def __init__(self, dataset, **kwargs):
super().__init__(**kwargs)
self.param.watch(self._update_itemplot_active_item, ["item"], onlychanged=True)
self.item_plot = ItemPlot(dataset)
def view(self):
return pn.Column(self.item_plot.view)
def view_params(self):
return pn.Column(self.param)
class ItemPlot(param.Parameterized):
active_item = param.Integer(default=1, bounds=(1, 5))
TOOLS = [TapTool(), ResetTool()]
def __init__(self, dataset, **kwargs):
super().__init__(**kwargs)
self.source = ColumnDataSource(dataset)
def _select_callback(self, attr, old, new):
print(old, new)
if new:
self.active_item = new[0] + 1
def view(self):
self.plot = figure(tools=self.TOOLS)
self.plot.scatter("x", "y", size=20, source=self.source)
self.source.selected.on_change("indices", self._select_callback)
self.source.selected.indices = [self.active_item - 1]
return self.plot
visualizer = pn.template.MaterialTemplate(title="My Visualizer")
vis = Visualizer(data)
visualizer.main.append(vis.view)
visualizer.sidebar.append(vis.view_params)
visualizer.servable()
If I change the Visualizer.item
param through the slider, the selected item in the plot is changed correctly (thanks to the watcher).
Also, if I click on the plot, it updates the selected item thanks to the TapTool
and the _select_callback
.
But what I’d like to achieve and I cannot, is updating the Visualizer.item
param from the ItemPlot
object.
What is the cleanest way to achieve this?
Thanks!