Welcome to the Streamlit community!
Thanks for the detailed question and screenshots—they really help! Your goal is to have st.pills dynamically update its available tags based on the filtered DataFrame, so only relevant tags are selectable after each search/filter action.
Currently, Streamlit’s st.pills widget (as of v1.52.0) does not natively support dynamic option updates in the same rerun—changing the options list for a widget will reset its selection, and the widget is re-instantiated, which can cause the selection to be lost or reset (see docs). To achieve the behavior you want, you need to carefully manage the widget’s options and its selected values in st.session_state, and ensure that after each filter, the pills widget is re-rendered with the new set of tags, while preserving only the valid selections.
Here’s a minimal reproducible example pattern you can adapt:
import streamlit as st
# Example: tags available in your filtered DataFrame
def get_available_tags(df):
# Replace with your logic to extract tags from df
return sorted(set(tag for tags in df['tags'] for tag in tags))
# Simulate a DataFrame with tags
import pandas as pd
df = pd.DataFrame({
"image": ["img1", "img2", "img3"],
"tags": [["red", "green"], ["green", "blue"], ["red", "blue", "yellow"]]
})
# Initialize session state for tag selection
if "selected_tags" not in st.session_state:
st.session_state.selected_tags = []
# Filter DataFrame based on selected tags
def filter_df(df, selected_tags):
if not selected_tags:
return df
return df[df['tags'].apply(lambda tags: any(tag in tags for tag in selected_tags))]
# Get available tags from filtered DataFrame
filtered_df = filter_df(df, st.session_state.selected_tags)
available_tags = get_available_tags(filtered_df)
# Remove any selected tags that are no longer available
st.session_state.selected_tags = [tag for tag in st.session_state.selected_tags if tag in available_tags]
# Pills widget with dynamic options
selected = st.pills("Tags", available_tags, selection_mode="multi", key="selected_tags")
# Update session state
st.session_state.selected_tags = selected
st.write("Selected tags:", st.session_state.selected_tags)
st.write("Available tags:", available_tags)
st.write(filtered_df)
This approach ensures that after each selection, the available tags update to reflect only those present in the filtered DataFrame, and the selection is always valid. If you want to see a more advanced or production-ready version, let us know!
Sources: