I am replicating the example given in the panel repo (panel/sinewave.py at master · holoviz/panel · GitHub), except I would like to not have the plot update until a button is pressed. As an aside, I need to use the button to simulate a lengthy computation, which is why it is necessary. Below is the code with the button and a peculiar requirement for a widget in order for the Bokeh plot to update.
I am working in Juptyer lab with
- panel 0.14.1
- bokeh 2.4.3
- param 1.12.3
- numpy 1.23.5
- jupyterlab 3.5.1
import numpy as np
import panel as pn
import param
from bokeh.models.sources import ColumnDataSource
from bokeh.plotting.figure import figure
pn.extension()
class WatchMethodExample(param.Parameterized):
amplitude = param.Number(default=1.0, bounds=(-5.0, 5.0))
frequency = param.Number(default=1.0, bounds=(0.1, 5.1))
N = param.Integer(default=200, bounds=(0, None))
offset = param.Number(default=0.0, bounds=(-5.0, 5.0))
phase = param.Number(default=0.0, bounds=(0.0, 2 * np.pi))
x_range = param.Range(default=(0, 4 * np.pi), bounds=(0, 4 * np.pi))
y_range = param.Range(default=(-2.5, 2.5), bounds=(-10, 10))
update = param.Event()
required_widget_display = param.Parameter(default="")
def __init__(self, **params):
super(WatchMethodExample, self).__init__(**params)
x, y = self.compute_data()
self.cds = ColumnDataSource({"x": x.tolist(), "y": y.tolist()})
self.plot = self.create_figure()
self.plot.line(x="x", y="y", source=self.cds)
def compute_data(self):
x = np.linspace(0, 4 * np.pi, self.N)
y = self.amplitude * np.sin(self.frequency * x + self.phase) + self.offset
return x, y
def create_figure(self):
return figure(
plot_height=400,
plot_width=400,
outline_line_color="black",
x_axis_label="x",
y_axis_label="y",
title="Sine wave",
x_range=self.x_range,
y_range=self.y_range,
)
@param.depends(
"amplitude",
"frequency",
"N",
"offset",
"phase",
"x_range",
"y_range",
"update",
watch="queued",
)
def update_plot(self):
if self.update is True:
# COMMENT OUT THE NEXT LINE
self.required_widget_display = np.random.randint(1)
x, y = self.compute_data()
self.cds.data = {"x": x.tolist(), "y": y.tolist()}
self.plot.x_range.start, self.plot.x_range.end = self.x_range
self.plot.y_range.start, self.plot.y_range.end = self.y_range
w = WatchMethodExample()
pn.Row(w.param, w.plot)
I cannot upload images, but if I comment out the line indicated in the above code, the Bokeh plot no longer updates. I’m assuming I’m not using the event correctly, but I’m not entirely sure.