Hi all. I have a parameterized class that calls and updates a class of bokeh plot objects using @pn.depends. Unfortunately this means that when I launch the server and update widgets the bokeh x-y range gets reset. I have looked over the prior exampels using hvplot and hv.DynamicMap and unfortunately hv.DynamicMap does not like taking a param object. I would prefer not to use the holoviews bokeh extension for 1) the simple reason that I’ve already coded things up and have this one sticky issue and 2) I like being able to not have to call a df directly in the plot line, such that it is simple to read how things are getting plotted (at least for me). Minimum reproducible example below.
import pandas as pd
import bokeh
import numpy as np
from bokeh.plotting import figure
import panel as pn
import param
data = {'x': np.random.rand(10),'y1': np.random.rand(10),'y2': np.random.rand(10), 'y3': np.random.rand(10)}
df = pd.DataFrame(data=data)
color_palette = bokeh.palettes.Muted9
class plots():
def __init__(self,*args):
super().__init__(*args)
for a in args:
self.__setattr__(str(a), args[0])
def line_plot(data,ys_to_plot,vert_line1,vert_line2):
fig = figure(height=500,width=500,tools='pan,reset,save,wheel_zoom,xwheel_zoom,ywheel_zoom')
for v,c in zip(ys_to_plot,color_palette):
fig.line(data['x'],data[v],line_width=0.7,legend_label='{}'.format(v),color=c)
fig.line([vert_line1,vert_line1],[0,1],line_width=0.4,line_dash='dashed',color='black')
fig.line([vert_line2,vert_line2],[0,1],line_width=0.4,line_dash='solid',color='black')
return fig
class update_plots(param.Parameterized):
ys_to_plot = param.ListSelector(default=['y1'], objects=['y1','y2','y3'])
vert_line1 = param.Number(default=0.2,bounds=(0,1))
vert_line2 = param.Number(default=0.8,bounds=(0,1))
def __init__(self,**params):
super().__init__(**params)
self.widgets = pn.Param(self,parameters=['ys_to_plot','vert_line1','vert_line2'])
@pn.depends('ys_to_plot','vert_line1','vert_line2')
def dynamic_plot(self):
return plots.line_plot(df,self.ys_to_plot,self.vert_line1,self.vert_line2)
callapp = update_plots(name='my application')
widgets = {'ys_to_plot': pn.widgets.CheckBoxGroup}
vanilla_layout = pn.template.VanillaTemplate(title='my application',
sidebar=pn.Column(pn.WidgetBox(pn.Param(callapp.param,widgets=widgets))),
sidebar_width=380)
vanilla_layout.main.append(pn.Row(callapp.dynamic_plot))
vanilla_layout.show();