如何将单个小部件的值传递给 Panel/Bokeh 中一个 object 的多个实例
How to pass values of a single widget to multiple instances of one object in Panel/Bokeh
我构建了一个仪表板来绘制数据集的各个部分,当我声明每个单独的组件时它就可以工作。由于我所有的图都很相似,只是标题和 select 要绘制的数据集的关键发生了变化,所以我尝试使用 class 来描述我的图,但我在传递小部件时遇到了问题绘图所有实例的值 class。
我在下面附上了一个例子。在单独的模型中,我得到一个小部件和两个图表,当我将小部件从 'a' 更改为 'b' 时,两个图都会按预期更新。但是在使用 classes 的模型中,当我更改小部件的值时,第一个图会更新,而第二个不会。我假设这是因为小部件只更改了第一个实例的 key_val,而不是第二个实例。
import pandas as pd
import panel as pn
import matplotlib.pyplot as plt
import param
pn.extension()
##separate model
data={'a':{'Set1':[[1,2],[10,20]],'Set2':[[3,4],[13,14]]},
'b':{'Set1':[[5,5],[6,16]],'Set2':[[10,20],[1,2]]}}
key_val = pn.widgets.Select(name='Choose dataset', options=['a','b'])
@pn.depends(key_val.param.value,watch=True)
def f1(key_val):
fig=plt.plot(data[key_val]['Set1'][0],data[key_val]['Set1'][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
@pn.depends(key_val.param.value,watch=True)
def f2(key_val):
fig=plt.plot(data[key_val]['Set2'][0],data[key_val]['Set2'][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
pn.Column(pn.WidgetBox(key_val), pn.Row(f1,f2))
##class model
class simple_plot(param.Parameterized):
key_val = param.Selector(default='a', objects=['a','b'])
my_second_option=param.String(default='Set1')
@param.depends('key_val',watch=True)
def f_both(self):
fig=plt.plot(data[self.key_val][self.my_second_option][0],
data[self.key_val][self.my_second_option][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
test=simple_plot()
test2=simple_plot(my_second_option='Set2')
pn.Row(test.param, pn.Row(test.f_both),pn.Row(test2.f_both))
所以我的问题是如何设置 class 和小部件,以便我可以为我的 class?
的两个实例传递小部件值
您可以创建一个class CommonParameters
来保存常用参数:
import pandas as pd
import panel as pn
import matplotlib.pyplot as plt
import param
pn.extension()
data = {
"a":{"Set1":([0, 1, 2], [1, 2, 3]),
"Set2":([0, 1, 2], [1, 3, 2]),
},
"b":{"Set1":([0, 10, 20], [1, 20, 3]),
"Set2":([0, 10, 20], [1, 3, 20]),
},
}
class CommonParameters(param.Parameterized):
key_val = param.Selector(default='a', objects=['a','b'])
class simple_plot(param.Parameterized):
parameters = param.ObjectSelector(precedence=-1)
my_second_option = param.String(default="Set1")
@param.depends('parameters.key_val',watch=True)
def f_both(self):
key_val = self.parameters.key_val
fig=plt.plot(data[key_val][self.my_second_option][0],
data[key_val][self.my_second_option][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
common_pars = CommonParameters()
test=simple_plot(name="test1", parameters=common_pars)
test2=simple_plot(name="test2", parameters=common_pars, my_second_option="Set2")
pn.Row(pn.Column(common_pars.param, test.param, test2.param), pn.Row(test.f_both),pn.Row(test2.f_both))
如果不需要编辑my_second_option
,可以使用:
pn.Row(common_pars.param, pn.Row(test.f_both), pn.Row(test2.f_both))
我构建了一个仪表板来绘制数据集的各个部分,当我声明每个单独的组件时它就可以工作。由于我所有的图都很相似,只是标题和 select 要绘制的数据集的关键发生了变化,所以我尝试使用 class 来描述我的图,但我在传递小部件时遇到了问题绘图所有实例的值 class。
我在下面附上了一个例子。在单独的模型中,我得到一个小部件和两个图表,当我将小部件从 'a' 更改为 'b' 时,两个图都会按预期更新。但是在使用 classes 的模型中,当我更改小部件的值时,第一个图会更新,而第二个不会。我假设这是因为小部件只更改了第一个实例的 key_val,而不是第二个实例。
import pandas as pd
import panel as pn
import matplotlib.pyplot as plt
import param
pn.extension()
##separate model
data={'a':{'Set1':[[1,2],[10,20]],'Set2':[[3,4],[13,14]]},
'b':{'Set1':[[5,5],[6,16]],'Set2':[[10,20],[1,2]]}}
key_val = pn.widgets.Select(name='Choose dataset', options=['a','b'])
@pn.depends(key_val.param.value,watch=True)
def f1(key_val):
fig=plt.plot(data[key_val]['Set1'][0],data[key_val]['Set1'][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
@pn.depends(key_val.param.value,watch=True)
def f2(key_val):
fig=plt.plot(data[key_val]['Set2'][0],data[key_val]['Set2'][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
pn.Column(pn.WidgetBox(key_val), pn.Row(f1,f2))
##class model
class simple_plot(param.Parameterized):
key_val = param.Selector(default='a', objects=['a','b'])
my_second_option=param.String(default='Set1')
@param.depends('key_val',watch=True)
def f_both(self):
fig=plt.plot(data[self.key_val][self.my_second_option][0],
data[self.key_val][self.my_second_option][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
test=simple_plot()
test2=simple_plot(my_second_option='Set2')
pn.Row(test.param, pn.Row(test.f_both),pn.Row(test2.f_both))
所以我的问题是如何设置 class 和小部件,以便我可以为我的 class?
的两个实例传递小部件值您可以创建一个class CommonParameters
来保存常用参数:
import pandas as pd
import panel as pn
import matplotlib.pyplot as plt
import param
pn.extension()
data = {
"a":{"Set1":([0, 1, 2], [1, 2, 3]),
"Set2":([0, 1, 2], [1, 3, 2]),
},
"b":{"Set1":([0, 10, 20], [1, 20, 3]),
"Set2":([0, 10, 20], [1, 3, 20]),
},
}
class CommonParameters(param.Parameterized):
key_val = param.Selector(default='a', objects=['a','b'])
class simple_plot(param.Parameterized):
parameters = param.ObjectSelector(precedence=-1)
my_second_option = param.String(default="Set1")
@param.depends('parameters.key_val',watch=True)
def f_both(self):
key_val = self.parameters.key_val
fig=plt.plot(data[key_val][self.my_second_option][0],
data[key_val][self.my_second_option][1])
curr_fig=plt.gcf()
plt.close(curr_fig)
return curr_fig
common_pars = CommonParameters()
test=simple_plot(name="test1", parameters=common_pars)
test2=simple_plot(name="test2", parameters=common_pars, my_second_option="Set2")
pn.Row(pn.Column(common_pars.param, test.param, test2.param), pn.Row(test.f_both),pn.Row(test2.f_both))
如果不需要编辑my_second_option
,可以使用:
pn.Row(common_pars.param, pn.Row(test.f_both), pn.Row(test2.f_both))