panel icon indicating copy to clipboard operation
panel copied to clipboard

Setting slider value programmatically does not update value_throttled parameter

Open TheoMathurin opened this issue 2 years ago • 5 comments

panel 0.12.1 param 1.11.1 bokeh 2.3.3

This is a continuation of #1256.

When changing the value parameter of a slider from python after instantiation, value_throttled is not updated. Then it's only when the user changes the slider value in the browser that the discrepancy between value_throttled and value disappears. I think all sliders are affected.

For instance with a FloatSlider, if you have the following:

import panel as pn

slider = pn.widgets.FloatSlider(name='Slider', start=0, end=1, value=0, step=0.1)
slider.value = 1

print(slider.value_throttled)

you will get 0 instead of 1.

This can have detrimental consequences, because if the slider value is changed based on some event, you cannot reliably make things depend on the value_throttled parameter, which can be at odds with value and with the state of the widget as displayed in the browser.

Because of this, there are situations where you can't use value_throttled when it's needed, for instance as arguments of a DynamicMap when you have high computational costs associated with a change of parameters.

TheoMathurin avatar Aug 27 '21 14:08 TheoMathurin

Has anyone found a solution to this problem? I am struggling with this... As far as I can tell, it is not possible to change the value_throttled parameter manually either because it is defined as constant?

oskar-veggeland avatar Jun 21 '22 12:06 oskar-veggeland

If you are using value_throttled in the context of a DynamicMap, you can just get the actual widget value, e.g.:


def make_plot(arg1):
    real_value = slider.value # instead of arg1 which may not be up to date
    ...

dmap = hv.DynamicMap(pn.bind(make_plot, arg1=slider.param.value_throttled))

TheoMathurin avatar Jun 21 '22 12:06 TheoMathurin

I want to be able to set the throttled slider value from a different callback in the code, e.g. from a button press.

button_handler(event): slider.param.set_param(value_throttled=SOMENUMBER)

This fails with an error saying that value_throttled is a constant parameter. I can change the 'value' parameter, but the problem is that I have a dynamic map relying on the throttled value. So changing slider.value from the button-press will not update the dynamic map...

oskar-veggeland avatar Jun 22 '22 06:06 oskar-veggeland

My suggestion is setting pn.extension(throttled=True) or pn.config.throttled=True. This will make all sliders value to work like value_throttled when interacting with widgets, and therefore you can use value in your code.

hoxbro avatar Jun 22 '22 07:06 hoxbro

Thanks @Hoxbro

In my case this does not help though. In fact I'm populating the slider's options dynamically which leads to some subtle but harmful behavior:

slider.options = ['A', 'B', 'C']
slider.value = 'B'
# User plays around with the slider and then loads some other data, which will update the options
slider.options = ['D', 'E', 'F']
slider.value = 'E'
# Here, value will be 'E' but value_throttled will remain whatever it was before among the previous options
# User changes value from 'E' to 'D' but the DynamicMap is not updated

The problem lies with the fact that when you change the options while value_throttled (or even value for that matter) is not among the options, in some sense it defaults to the first option. Therefore when you slide to the first option, no event will be triggered. I can make an video illustrating this behavior if needed.

I guess one solution would be to instantiate a new slider instead of updating the existing instance but that's not ideal for me. Another would be to always initialize the slider to the first value but it will not be appropriate in some situations.

TheoMathurin avatar Jun 28 '22 16:06 TheoMathurin

The implementation of value_throttled in Player (#3756) means they are now subject to the same issue as ordinary sliders. That leads to apparently even weirder behavior although I will have to double check that.

Edit: turns out the weird behavior I noticed is due to a separate issue (see #3965)

TheoMathurin avatar Oct 06 '22 13:10 TheoMathurin