Slider doesn't drag and update when based on `session_state`

Summary

I have 2 sliders, first one works perfect, second one works perfect too until I make its value based on a value in the session_state. Then, when I drag the slider, the slider stops and I have to unclick, reclick, and drag again.

Steps to reproduce

Code snippet:

mu = st.slider('$\mu$', 0.0, 5.0, 2.5, step=0.1)
var = st.slider('$\sigma^2$', 0.0, mu, min(mu, st.session_state.var) if 'var' in st.session_state else 1.0, step=0.1, key='var')

If applicable, please provide the steps we should take to reproduce the error or specified behavior.

Expected behavior:

When I drag the σ² slider, it should continuously update the message below while dragging.

Actual behavior:

When I drag the σ² slider, it stops dragging the moment the message below is updated.

Debug info

  • Streamlit version: 1.17 (but also happening on Streamlit Cloud)
  • Python version: 3.10
  • pip
  • OS version: macOS 13.2.1
  • Browser version: Chrome 110

Requirements file

No requirements file necessary

Links

Additional information

If modifying the var = st.slider(...) line to make the value dependent on anything other than session_state makes the dragging work perfect. Problem persists if I create a new variable before this var = st.slider(...) line to be the value based on session_state.var.

I think I understand. Because you are changing the creation parameters of the second slider, you are in fact getting a completely different widget with each update. That’s why you can’t “keep hold” of the selector knob.

I think this would then be expected behavior and you’d need a custom component if you want dynamically set the max value of the slider without it creating a new widget each time.

1 Like

Thank you @mathcatsand, that makes sense. Though it’s not just that changing parameters of the var slider prevents dragging from working properly. For example, when the var slider’s max_value is set to mu and its value is set to something involving mu, then the dragging works perfect. It’s only when the creation parameter for value involves session_state that the dragging issue appears.

It’s the changing of the default value that’s doing it.

As I thought about it, you can get around this by not using the default value to change its value and instead using session_state to assign it. (In the middle of something now, so I can post an example in a little bit.)

1 Like

Thank you @mathcatsand, eager to see your example!

Try this:

import streamlit as st

mu = st.slider('$\mu$', 0.0, 5.0, 2.5, step=0.1)

if 'var' in st.session_state:
    st.session_state.var = min(mu, st.session_state.var)

var = st.slider('$\sigma^2$', 0.0, mu, min(1.0,mu), step=0.1, key='var')
1 Like

This worked! Thank you. I changed the argument min(1.0,mu) to just 1.0 and that worked the same. I saw a warning when I first tried this and then the warning went away as a slid the slider. So I didn’t read it. And I can’t reproduce the warning now.

I didn’t know you could set slider values this way. Thank you.

ok, I published and now it’s easy to see the warning:

The widget with key “var” was created with a default value but also had its value set via the Session State API.

What do you suggest? Is that a problem? If not a problem, can I suppress that warning?

It’s a kind of hit or miss error I get sometimes that I too have a hard time reproducing consistently on demand. I usually get it while doing live edits. It’s not really a problem, as far as I know.

If you get rid of min(1.0,mu) your second slider is going to get stuck with a max of 1.0 if you take mu<1.0, just fyi.

1 Like

There’s no way to suppress that warning? I just don’t want users to see it.

You’re right, thank you. But why? Why does setting the value, as opposed to the max_value, keep the max_value ≥ 1.0?

The documentation doesn’t say explicitly, so I’d have to look closer at the code to say for sure, but the effect appears to be: if you set an initial value that is greater than your declared max, then that initial value becomes the max.

Are you getting the warning from a fresh restart of the app, or just sometimes in the middle of editing code on a live app? I’m not sure on disabling; I’ll have to dig a bit…

1 Like

That makes sense. Thank you for explaining.

Just on a fresh start of the app it seems. But I can’t always reproduce it.

Here is a more robust solution that avoids the error. I didn’t know how you wanted to handle mu == 0.0 so I just hid the second slider. You can avoid a few of these lines if you don’t allow mu to go to zero and break the second slider.

import streamlit as st

if 'default' not in st.session_state:
    st.session_state.default = 1.0

def set_default():
    if 'var' in st.session_state:
        st.session_state.default = min(st.session_state.var, st.session_state.mu)

mu = st.slider('$\mu$', 0.0, 5.0, 2.5, step=0.1, key='mu', on_change=set_default)

if mu > 0.0:
    var = st.slider('$\sigma^2$', 0.0, mu, st.session_state.default, step=0.1, key='var')
1 Like

Glad to see @mathcatsand helped you find a workaround (thank you, @mathcatsand :pray:)! I’ve updated the StackOverflow thread to share her suggestions there too

1 Like

Thank you @mathcatsand. Appreciate the mu positivity check as well!

1 Like

Thank you for following up @Caroline!

1 Like