[英]Why is my plot updated by panel (twice) when I change a button setting that shouldn't trigger any updates? (Panel Holoviz)
I made a class to explore and train models.我制作了一个 class 来探索和训练模型。
When I change the value of dropdown 'choose_model_type' in the code example below, I would expect nothing to change in my dashboard, since there are no @param.depends('choose_model_type', watch=True)
in my class.当我在下面的代码示例中更改下拉菜单“choose_model_type”的值时,我希望仪表板中没有任何变化,因为我的 class 中没有@param.depends('choose_model_type', watch=True)
。 However, my dashboard gets updated, when I change the value of dropdown 'choose_model_type'.但是,当我更改下拉菜单“choose_model_type”的值时,我的仪表板会更新。 In this case function plot_y() gets triggered twice if I look at the logs:在这种情况下,如果我查看日志,function plot_y() 会被触发两次:
2019-09-26 11:24:42,802 starting plot_y 2019-09-26 11:24:42,802 开始 plot_y
2019-09-26 11:24:42,825 starting plot_y 2019-09-26 11:24:42,825 开始 plot_y
This is for me unexpected behavior.这对我来说是意想不到的行为。 I don't want plot_y() to be triggered when I change 'choose_model_type'.我不希望在更改“choose_model_type”时触发 plot_y()。
How do i make sure that plot_y gets triggered only when 'y' changes (and my plot is updated in the dashboard) and not when other parameters such as dropdown change?如何确保 plot_y 仅在“y”更改时触发(并且我的 plot 在仪表板中更新)而不是在其他参数(例如下拉菜单)更改时触发?
I want to control what gets triggered when, but for me there seems to be some magic going on.我想控制什么时候触发,但对我来说似乎有一些魔法正在发生。
Other related question is:其他相关问题是:
Why does plot_y() get triggered twice?为什么 plot_y() 被触发两次? If I change 'pred_target' it also triggers plot_y() twice.如果我更改 'pred_target' 它也会触发 plot_y() 两次。 Same happens when I change the value of 'choose_model_type': plot_y() gets triggered twice.当我更改“choose_model_type”的值时也会发生同样的情况:plot_y() 被触发两次。
# library imports
import logging
import numpy as np
import pandas as pd
import hvplot
import hvplot.pandas
import holoviews as hv
from holoviews.operation.datashader import datashade, dynspread
hv.extension('bokeh', logo=False)
import panel as pn
import param
# create some sample data
df = pd.DataFrame(np.random.choice(100, size=[50, 2]), columns=['TARGET1', 'TARGET2'])
# class to train my models with some settings
class ModelTrainer(param.Parameterized):
logging.info('initializing class')
pred_target = param.Selector(
default='TARGET1',
objects=['TARGET1', 'TARGET2'],
label='Choose prediction target'
)
choose_model_type = param.Selector(
default='LINEAR',
objects=['LINEAR', 'LGBM', 'RANDOM_FOREST'],
label='Choose type of model',
)
y = df[pred_target.default]
# i expect this function only to be triggered when pred_target changes
@param.depends('pred_target', watch=True)
def _reset_variables(self):
logging.info('starting reset variables')
self.y = df[self.pred_target]
# i expect plot_y() only to be triggered when y changes
@param.depends('y', watch=True)
def plot_y(self):
logging.info('starting plot_y')
self.y_plot = dynspread(datashade(self.y.hvplot.scatter()))
return self.y_plot
model_trainer = ModelTrainer()
# show model dashboard
pn.Column(
pn.Row(model_trainer.param['pred_target']),
pn.Row(model_trainer.param['choose_model_type']),
pn.Row(model_trainer.plot_y)
).servable()
The problem here is one of validation, specifically the issue is here: @param.depends('y', watch=True)
.这里的问题是验证之一,特别是问题在这里: @param.depends('y', watch=True)
。 y
is not a parameter in your example, therefore param.depends can't resolve it and ends up falling back to depending on all parameters. y
在您的示例中不是参数,因此 param.depends 无法解决它并最终退回到取决于所有参数。 I've filed an issue to resolve this here .我已经提交了一个问题来解决这个问题。 If you change your example to:如果您将示例更改为:
y = param.Series(default=df[pred_target.default])
It will work, however you will still have the issue with the callback being called twice.它会起作用,但是您仍然会遇到回调被调用两次的问题。 This is because you have set watch=True
in the depends declaration.这是因为您在依赖声明中设置了watch=True
。 Setting watch=True
only makes sense for methods that have side-effects, if your method is something that returns a value then it will rarely make sense to set it.设置watch=True
仅对具有副作用的方法有意义,如果您的方法是返回值的方法,那么设置它几乎没有意义。 To expand on that, when you pass the method to panel, eg pn.Row(model_trainer.plot_y)
, it will automatically watch the parameters and call the method to update the plot when the parameters change.进一步扩展,当您将方法传递给面板时,例如pn.Row(model_trainer.plot_y)
,它将自动监视参数并在参数更改时调用该方法来更新 plot。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.