Multiple sliders with dependant values

Is there a way to make values of multiple sliders dependent on each other?

For example, suppose we have three sliders: x1, x2, and x3. I want:

  1. the value of x2 and x3 gets updated automatically when I change x1 as x2 = x1 / 2 and x3 = x1 / 2
  2. and the value of x1 gets updated automatically when I change x2 and x3 as x1 = x2 + x3

Item 1 is achieved easily in isolation:

x1 = st.slider("x1", 1.0, 100.0)

val0 = x1 / 2
x2 = st.slider("x2", 1.0, 100.0, val0)
x3 = st.slider("x3", 1.0, 100.0, val0)

But I want both to happen simultaneously. When I change x1, the values of x2 and x3 get updated and when I change x2 and x3, the value of x1 to be updated.

Is there a way to to do this?

1 Like

I had the exact same problem and solved it with session state. Here is the code for the four sliders:

import streamlit as st

# streamlit preparation
st.title('Four dependent sliders')

# Session state callbacks
def callback_x1():
    """The callback renormalizes the values that were not updated."""
    # Here, if we modify X1, we calculate the remaining value for normalisation of X2, X3 and X4
    remain = 100 - st.session_state.x1
    # This is the proportions of X2, X3 and X4 in remain
    sum = st.session_state.x2 + st.session_state.x3 + st.session_state.x4
    # This is the normalisation step
    st.session_state.x2 = st.session_state.x2/sum*remain
    st.session_state.x3 = st.session_state.x3/sum*remain
    st.session_state.x4 = st.session_state.x4/sum*remain

def callback_x2():
    remain = 100 - st.session_state.x2
    sum = st.session_state.x1 + st.session_state.x3 + st.session_state.x4
    st.session_state.x1 = st.session_state.x1/sum*remain
    st.session_state.x3 = st.session_state.x3/sum*remain
    st.session_state.x4 = st.session_state.x4/sum*remain

def callback_x3():
    remain = 100 - st.session_state.x3
    sum = st.session_state.x1 + st.session_state.x2 + st.session_state.x4
    st.session_state.x1 = st.session_state.x1/sum*remain
    st.session_state.x2 = st.session_state.x2/sum*remain
    st.session_state.x4 = st.session_state.x4/sum*remain

def callback_x4():
    remain = 100 - st.session_state.x4
    sum = st.session_state.x1 + st.session_state.x2 + st.session_state.x3
    st.session_state.x1 = st.session_state.x1/sum*remain
    st.session_state.x2 = st.session_state.x2/sum*remain
    st.session_state.x3 = st.session_state.x3/sum*remain

# Sessions tate initialise
# Check if 'key' already exists in session_state
# If not, then initialize it
if 'x1' not in st.session_state:
    st.session_state['x1'] = 50.0

if 'x2' not in st.session_state:
    st.session_state['x2'] = 25.0

if 'x3' not in st.session_state:
    st.session_state['x3'] = 12.5

if 'x4' not in st.session_state:
    st.session_state['x4'] = 12.5

# The four sliders
st.slider("x1 value, %",
                min_value = 0.0,
                max_value = 100.0,
                key='x1', on_change=callback_x1)

st.slider("x2 value, %",
                min_value = 0.0,
                max_value = 100.0,
                key='x2', on_change=callback_x2)

st.slider("x3 value, %",
                min_value = 0.0,
                max_value = 100.0,
                key='x3', on_change=callback_x3)

st.slider("x4 value, %",
                min_value = 0.0,
                max_value = 100.0,
                key='x4', on_change=callback_x4)

# Print things to check
st.write(st.session_state.x1 + st.session_state.x2 + st.session_state.x3 + st.session_state.x4)
st.write(st.session_state.x1)
st.write(st.session_state.x2)
st.write(st.session_state.x3)
st.write(st.session_state.x4)

Hi, it is not difficult to achieve, you can just send previous value to second or third slider
Code example:

a = st.slider("argument1", min_value=0, max_value=10, step=1)
b = st.slider("argument2", min_value=a, max_value=20, step=1)

before I change first slider value:


after I change first slider value:

@BeyondMyself But how to acheive the 2nd case

Here is a more general-purpose structure. Note that the default configuration of the sliders means it breaks the formula for large numbers or fractions, so additional settings on the sliders or conditionals are needed to make it fully robust. This is just the minimum code to show a possible structure.

def update (change):
    if change == 'x1':
        st.session_state.x2 = st.session_state.x1 / 2
        st.session_state.x3 = st.session_state.x1 / 2
    else:
        st.session_state.x1 = st.session_state.x2 + st.session_state.x3

st.slider('x1', value=2, key='x1', on_change=update, args=('x1',))
st.slider('x2', value=1, key='x2', on_change=update, args=('x2',))
st.slider('x3', value=1, key='x3', on_change=update, args=('x3',))