Cross filter in multiselct based on values in other multiselct boxes

Hi everyone!
Could you please help me to solve the following problem:

I have a table like this:

data = {
    'Level 1': ['A', 'A', 'B', 'B', 'C', 'C'],
    'Level 2': ['X', 'Y', 'X', 'Y', 'X', 'Y'],
    'Level 3': ['1', '2', '1', '2', '1', '2'],
    'Car ': ['Car 1', 'Car 2', 'Car 3', 'Car 4', 'Car 5', 'Car 6'],
    'Amount': [10, 20, 30, 40, 50, 60]
}

I’d like to add 3 multiselect boxes to sidebar (options to choose values in Level 1, Level 2, Level 3) so that if something checked in any box or boxes, values in the other boxes should be also filterd accordingly.

The main problem is that nobody knows what filter will be used first. For example, someone can choose 1 in Level 3, so in the filter level 2 values should be X, for Level 1, A, B,C. Someone can start from Level 2 and so on.

Hope you can give me some ideas how to do it, thank you very much!

1 Like

Hi @Belka,

Thanks for posting!

Here’s an implementation of the scenario you described above. The filters are interdependent and changes reflect in real-time. Might need some tweaks on your side to fit your use case better:

import streamlit as st
import pandas as pd

# Sample data
data = {
    'Level 1': ['A', 'A', 'B', 'B', 'C', 'C'],
    'Level 2': ['X', 'Y', 'X', 'Y', 'X', 'Y'],
    'Level 3': ['1', '2', '1', '2', '1', '2'],
    'Car ': ['Car 1', 'Car 2', 'Car 3', 'Car 4', 'Car 5', 'Car 6'],
    'Amount': [10, 20, 30, 40, 50, 60]
}
df = pd.DataFrame(data)

# Initialize session state
if 'selected_1' not in st.session_state:
    st.session_state.selected_1 = []
if 'selected_2' not in st.session_state:
    st.session_state.selected_2 = []
if 'selected_3' not in st.session_state:
    st.session_state.selected_3 = []

# Filter function
def filter_df(df, selected_1, selected_2, selected_3):
    if selected_1:
        df = df[df['Level 1'].isin(selected_1)]
    if selected_2:
        df = df[df['Level 2'].isin(selected_2)]
    if selected_3:
        df = df[df['Level 3'].isin(selected_3)]
    return df

# Initial filtering
df_filtered = filter_df(df, st.session_state.selected_1, st.session_state.selected_2, st.session_state.selected_3)

# Sidebar with selectors
st.session_state.selected_1 = st.sidebar.multiselect(
    'Level 1', df['Level 1'].unique(), st.session_state.selected_1)
st.session_state.selected_2 = st.sidebar.multiselect(
    'Level 2', df_filtered['Level 2'].unique(), st.session_state.selected_2)
st.session_state.selected_3 = st.sidebar.multiselect(
    'Level 3', df_filtered['Level 3'].unique(), st.session_state.selected_3)

# Final filtering based on user input and display
df_filtered = filter_df(df, st.session_state.selected_1, st.session_state.selected_2, st.session_state.selected_3)
st.table(df_filtered)