咨询:用Streamlit/Dash实现多依赖动态下拉筛选的可行性
动态依赖下拉筛选:Streamlit痛点与Dash可行性咨询
项目背景与需求
正在开发一个小项目,需要用Python可视化DataFrame,要求用户能对continent、country、language三个存在相互依赖关系的列进行筛选。
示例DataFrame代码如下:
import pandas as pd df = pd.DataFrame( { "continent": ["Asia"] * 2 + ["Europe"] * 2 + ["North America"] * 2, "country": ["China", "Japan"] + ["United Kingdom", "France"] + ["United States", "Canada"], "language": ["Chinese", "Japanese"] + ["English", "French"] + ["English", "English"], } )
具体筛选需求
- 用户选择
continent = North America后,country选项应缩小为United States和Canada,language选项仅保留English;若切换为continent = Europe,country和language选项需同步更新为欧洲对应内容 - 用户先选择
language = English后,continent选项应缩小为North America和Europe(使用英语的国家为Canada、United States和United Kingdom)
这类筛选存在非线性依赖关系。
Streamlit尝试情况
尝试用Streamlit结合callback实现,但发现Streamlit似乎不适合处理复杂依赖场景。
已用Streamlit实现一个MVP,下拉菜单具备动态效果,但由于选项依赖筛选后的DataFrame,用户选择后只能通过“Refresh Data”按钮重置,体验不佳。代码如下:
import pandas as pd import streamlit as st st.set_page_config(page_title="Toy App", layout="wide") @st.cache def get_data(): df = pd.DataFrame( { "Continent": ["Asia"] * 2 + ["Europe"] * 2 + ["North America"] * 2, "Country": ["China", "Japan"] + ["United Kingdom", "France"] + ["United States", "Canada"], "Language": ["Chinese", "Japanese"] + ["English", "French"] + ["English", "English"], } ) return df def update_df(df: pd.DataFrame) -> pd.DataFrame: continent = st.session_state["Continent"] country = st.session_state["Country"] language = st.session_state["Language"] if continent != "all": df = df.query(f"Continent == '{continent}'") if country != "all": df = df.query(f"Country == '{country}'") if language != "all": df = df.query(f"Language == '{language}'") st.session_state["df"] = df st.session_state["fresh_data"] = False df = get_data() if "df" not in st.session_state: st.session_state.df = df if "fresh_data" not in st.session_state: st.session_state.fresh_data = True with st.expander("Display", expanded=True): if st.button("Refresh data"): df = get_data() st.session_state["df"] = df st.session_state["fresh_data"] = True df = st.session_state["df"] col1, col2, col3 = st.columns(3) continent_options = df.Continent.unique().tolist() country_options = df.Country.unique().tolist() language_options = df.Language.unique().tolist() if st.session_state.fresh_data: country_options.insert(0, "all") language_options.insert(0, "all") continent_options.insert(0, "all") continent = col1.selectbox( "Continent", options=continent_options, on_change=update_df, kwargs={"df": df}, key="Continent", ) countries = col2.selectbox( "Country", options=country_options, on_change=update_df, kwargs={"df": df}, key="Country", ) language = col3.selectbox( "Language", options=language_options, on_change=update_df, kwargs={"df": df}, key="Language", ) st.write(df.astype("object"))
核心疑问
是否可以用Dash构建这类复杂依赖的动态下拉筛选?
内容的提问来源于stack exchange,提问作者bayes2021
相关产品推荐
相关产品推荐

