Почему мой график обновляется панелью (дважды), когда я изменяю настройку кнопки, которая не должна вызывать никаких обновлений? (Панно Головиз)

Я создал класс для изучения и обучения моделей.

Когда я изменяю значение раскрывающегося списка «choose_model_type» в приведенном ниже примере кода, я не ожидал, что на моей панели управления ничего не изменится, поскольку в моем классе нет @param.depends('choose_model_type', watch=True). Однако моя панель управления обновляется, когда я изменяю значение раскрывающегося списка «choose_model_type». В этом случае функция plot_y () запускается дважды, если я смотрю журналы:

2019-09-26 11: 24: 42,802 начальный сюжет_y
2019-09-26 11: 24: 42,825 начальный сюжет_y

Это для меня неожиданное поведение. Я не хочу, чтобы plot_y () запускался, когда я изменяю 'choose_model_type'.
Как мне убедиться, что plot_y запускается только при изменении 'y' (и мой график обновляется на панели инструментов), а не когда другие такие параметры, как изменение раскрывающегося списка?
Я хочу контролировать, что и когда срабатывает, но мне кажется, что здесь творится какая-то магия.

Другой связанный с этим вопрос:
Почему plot_y () запускается дважды? Если я изменю «pred_target», он также дважды вызовет plot_y (). То же самое происходит, когда я меняю значение '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()

dropdown_changes_dashboard_shouldnt_happen


person Sander van den Oord    schedule 26.09.2019    source источник
comment
Я думаю, что ответ Филиппа решает вашу проблему, но обратите внимание, что Param предполагает, что все методы могут зависеть от всех параметров в классе при отсутствии какого-либо более конкретного объявления. Объявление depends будет ограничивать то, от чего, как предполагается, зависит этот метод, а не дополнять его, в дополнение к любому наблюдению, которое он может разрешить.   -  person James A. Bednar    schedule 26.09.2019


Ответы (1)


Проблема здесь связана с проверкой, в частности проблема здесь: @param.depends('y', watch=True). y не является параметром в вашем примере, поэтому param.depends не может его разрешить и в конечном итоге возвращается в зависимости от всех параметров. Я подал заявку на решение этой проблемы здесь. Если вы измените свой пример на:

y = param.Series(default=df[pred_target.default])

Это будет работать, однако у вас по-прежнему будет проблема с двойным вызовом обратного вызова. Это потому, что вы установили watch=True в объявлении зависимостей. Установка watch=True имеет смысл только для методов, которые имеют побочные эффекты, если ваш метод является чем-то, что возвращает значение, тогда его установка не имеет смысла. Чтобы расширить это, когда вы передаете метод панели, например pn.Row(model_trainer.plot_y), он автоматически отслеживает параметры и вызывает метод обновления графика при изменении параметров.

person philippjfr    schedule 26.09.2019
comment
Спасибо @philippjfr, это очень-очень помогло. Я застрял в этой проблеме. Он работает в этом примере класса, сейчас попробую его на моей реальной (большей) приборной панели. - person Sander van den Oord; 26.09.2019