Session state logic

Idea:
Say I have 4 checkboxes with keys A, B, C, D and I also have a dataframe with A, B, C, D as indexes and all of them having some default value, like this:

import pandas as pd
import streamlit as st

df = pd.DataFrame(index = [‘A’, ‘B’, ‘C’, ‘D’], columns = [‘Value’, ‘Active’], data = [[1, False], [2, False], [3, False], [4, False]])

df[‘Active’].loc[‘A’] = st.checkbox(‘A’)
df[‘Active’].loc[‘B’] = st.checkbox(‘B’)
df[‘Active’].loc[‘C’] = st.checkbox(‘C’)
df[‘Active’].loc[‘D’] = st.checkbox(‘D’)

My goal is to create a data editor filtering only the “active keys” (determined by the checkboxes), this is my previous attempt:

st.data_editor(df[df[‘Active’] == True][‘Value’])

So let’s say we click on the checkbox “C”, it should create a new row with in the data editor.

Problem:
The problem is that everytime we click on the checkbox the code gets run again so it resets all values that may have been changed to the default. Example: we activate “A” and change the value to 37, but then activate “B”, when “B” is activated the row “A” returns to the default value of 1, but I want it to keep 37.

I guess the solution may have something with session states but I just can’t figure it out! Thanks for the attention

Yes, you would need to implement session state as in code below.

import pandas as pd
import streamlit as st

# Step 1: Initialize the DataFrame in the session state
if 'df' not in st.session_state:
    st.session_state['df'] = pd.DataFrame(index=['A', 'B', 'C', 'D'], columns=['Value', 'Active'], data=[[1, False], [2, False], [3, False], [4, False]])

# Step 2: Activate rows based on checkbox selections
st.session_state['df']['Active'].loc['A'] = st.checkbox('A')
st.session_state['df']['Active'].loc['B'] = st.checkbox('B')
st.session_state['df']['Active'].loc['C'] = st.checkbox('C')
st.session_state['df']['Active'].loc['D'] = st.checkbox('D')

# Step 3 & 4: Edit values and reflect changes back in the session state
active_df = st.session_state['df'][st.session_state['df']['Active'] == True].copy()
edited_df = st.data_editor(active_df['Value'])

if edited_df is not None:
    st.session_state['df']['Value'].update(edited_df)

Screen Recording 2023-09-15 at 3_scaling-0.5_fps-20_speed-5.0_duration-0-11

1 Like

Thank you very very very very much! It worked :slight_smile:

1 Like

Great! Glad it worked. Happy Streamlit-ing!:balloon:

Tony, I don’t know why, I just changed a little bit of your code to be like this:

import pandas as pd
import streamlit as st

if 'df' not in st.session_state:
    st.session_state['df'] = pd.DataFrame(
      index=['A', 'B', 'C', 'D'], 
      columns=['Low', 'High', 'Active'], 
      data=[[.0, 50., False], [.0, 500., False], [.1, 1.5, False], [.0, 50., False]])

st.session_state['df']['Active'].loc['A'] = st.checkbox('A')
st.session_state['df']['Active'].loc['B'] = st.checkbox('B')
st.session_state['df']['Active'].loc['C'] = st.checkbox('C')
st.session_state['df']['Active'].loc['D'] = st.checkbox('D')

active_df = st.session_state['df'][st.session_state['df']['Active'] == True].copy()
edited_df = st.data_editor(active_df[['Low', 'High']])
 
if edited_df is not None:
st.session_state['df'][['Low', 'High']].update(edited_df)

I changed the column “Value” to be 2 columns “Low” & “High” and now is not working anymore

You can try updating each column separately as the original update code is trying to update multiple columns all at once causing an error. See the updated code below:

import pandas as pd
import streamlit as st

if 'df' not in st.session_state:
    st.session_state['df'] = pd.DataFrame(
      index=['A', 'B', 'C', 'D'], 
      columns=['Low', 'High', 'Active'], 
      data=[[.0, 50., False], [.0, 500., False], [.1, 1.5, False], [.0, 50., False]])

st.session_state['df']['Active'].loc['A'] = st.checkbox('A')
st.session_state['df']['Active'].loc['B'] = st.checkbox('B')
st.session_state['df']['Active'].loc['C'] = st.checkbox('C')
st.session_state['df']['Active'].loc['D'] = st.checkbox('D')

active_df = st.session_state['df'][st.session_state['df']['Active'] == True].copy()
edited_df = st.data_editor(active_df[['Low', 'High']])
 
if edited_df is not None:
    for idx, row in edited_df.iterrows():
        st.session_state['df'].loc[idx, ['Low', 'High']] = row['Low'], row['High']

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.