Plot never updates when I change slider values

Hi
Can you tell me why plot never updates when I change slider values

import numpy as np
import panel as pn
import param
from bokeh.plotting import figure

class MyPlot(param.Parameterized):
    x_range = param.Range(default=(0, 10), bounds=(0, 100), doc="Range for x-axis")
    y_range = param.Range(default=(0, 10), bounds=(0, 100), doc="Range for y-axis")
    num_points = param.Integer(default=50, bounds=(10, 1000), doc="Number of points to plot")
    
    def __init__(self, **params):
        super().__init__(**params)
        self._plot = figure(title="My Plot")
        self._line = self._plot.line([], [])

    @param.depends("x_range", "y_range", "num_points", watch=True)
    def update_plot(self):
        x = np.linspace(self.x_range[0], self.x_range[1], self.num_points)
        y = np.random.normal(size=self.num_points) + np.sin(x)
        self._line.data_source.data = {"x": x, "y": y}
        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
        return self._plot

my_plot = MyPlot()

x_slider = pn.widgets.RangeSlider(name="X Range", start=0, end=100, value=(0, 10), margin=(50, 0, 0, 0))
y_slider = pn.widgets.RangeSlider(name="Y Range", start=0, end=100, value=(0, 10), margin=(50, 0, 0, 0))
num_points_slider = pn.widgets.IntSlider(name="Num Points", start=10, end=1000, value=50, margin=(50, 0, 0, 0))

pn.Row(my_plot.update_plot, pn.Column(x_slider, y_slider, num_points_slider), sizing_mode="stretch_both").servable()

regards

2 Likes

It’s because you declare 3 widgets but never bind them to anything :slight_smile:

This code works

import numpy as np
import panel as pn
import param
from bokeh.plotting import figure

class MyPlot(param.Parameterized):
    x_range = param.Range(default=(0, 10), bounds=(0, 100), doc="Range for x-axis")
    y_range = param.Range(default=(0, 10), bounds=(0, 100), doc="Range for y-axis")
    num_points = param.Integer(default=50, bounds=(10, 1000), doc="Number of points to plot")
    
    def __init__(self, **params):
        super().__init__(**params)
        self._plot = figure(title="My Plot")
        self._line = self._plot.line([], [])

    @param.depends("x_range", "y_range", "num_points")
    def update_plot(self):
        x = np.linspace(self.x_range[0], self.x_range[1], self.num_points)
        y = np.random.normal(size=self.num_points) + np.sin(x)
        self._line.data_source.data = {"x": x, "y": y}
        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
        return self._plot

my_plot = MyPlot()

x_slider = pn.widgets.RangeSlider.from_param(my_plot.param.x_range, name="X Range", start=0, end=100, value=(0, 10), margin=(50, 0, 0, 0))
y_slider = pn.widgets.RangeSlider.from_param(my_plot.param.y_range, name="Y Range", start=0, end=100, value=(0, 10), margin=(50, 0, 0, 0))
num_points_slider = pn.widgets.IntSlider.from_param(my_plot.param.num_points, name="Num Points", start=10, end=1000, value=50, margin=(50, 0, 0, 0))

pn.Row(my_plot.update_plot, pn.Column(x_slider, y_slider, num_points_slider), sizing_mode="stretch_both").servable()

1 Like

Thank you