Why is my plot updated by panel (twice) when I change a button setting that shouldn't trigger any updates? (Panel Holoviz)

 ̄綄美尐妖づ 提交于 2021-01-29 08:34:37

问题


I made a class to explore and train models.

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. However, my dashboard gets updated, when I change the value of dropdown 'choose_model_type'. In this case function plot_y() gets triggered twice if I look at the logs:

2019-09-26 11:24:42,802 starting plot_y
2019-09-26 11:24:42,825 starting plot_y

This is for me unexpected behavior. I don't want plot_y() to be triggered when I change 'choose_model_type'.
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?
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? If I change 'pred_target' it also triggers plot_y() twice. Same happens when I change the value of 'choose_model_type': plot_y() gets triggered twice.

# 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()


回答1:


The problem here is one of validation, specifically the issue is here: @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. 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. 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. To expand on that, when you pass the method to panel, e.g. pn.Row(model_trainer.plot_y), it will automatically watch the parameters and call the method to update the plot when the parameters change.



来源:https://stackoverflow.com/questions/58114082/why-is-my-plot-updated-by-panel-twice-when-i-change-a-button-setting-that-shou

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!