panel
panel copied to clipboard
Setting slider value programmatically does not update value_throttled parameter
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.
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?
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))
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...
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.
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.
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)