refactor: simplify Explorer to 3 focused tabs — compass, trajectories, SVD
Removes embedding-heavy search and generic browser tabs from the Explorer. The project does not currently use embeddings meaningfully, so the similarity search and browser features were dead weight. Changes: - explorer.py: Remove search and browser tabs, keep compass/trajectories/SVD - explorer.py: Remove fused_embeddings and similarity_cache stats from sidebar - Home.py: Update Explorer description to match new focused layout - analysis/tabs/__init__.py: Remove search and browser exports - tests: Update decomposition and import tests for new tab set Result: Explorer now has 3 focused analytical tabs instead of 5.
This commit is contained in:
@@ -19,8 +19,8 @@ def main() -> None:
|
||||
st.markdown(
|
||||
"**Motief** brengt de Nederlandse Tweede Kamer in kaart op basis van "
|
||||
"echte stemmingen over moties. Gebruik de Stemwijzer om te ontdekken welke "
|
||||
"partij het beste bij jouw standpunten past, of verken de politieke ruimte "
|
||||
"zelf in de Explorer."
|
||||
"partij het beste bij jouw standpunten past, of verken het politieke landschap "
|
||||
"in de Explorer: kompas, trajecten en SVD-analyse."
|
||||
)
|
||||
|
||||
st.divider()
|
||||
@@ -39,7 +39,7 @@ def main() -> None:
|
||||
st.subheader("🔭 Politiek Explorer")
|
||||
st.markdown(
|
||||
"Verken het politieke kompas, partijtrajecten door de tijd, "
|
||||
"en zoek vergelijkbare moties op in het archief."
|
||||
"en de onderliggende SVD-componenten die de assen vormen."
|
||||
)
|
||||
st.page_link("pages/2_Explorer.py", label="Open Explorer", icon="🔭")
|
||||
|
||||
|
||||
@@ -6,16 +6,12 @@ Each module contains a `build_<tab>_tab()` function that implements one tab.
|
||||
|
||||
from analysis.tabs.compass import build_compass_tab
|
||||
from analysis.tabs.trajectories import build_trajectories_tab
|
||||
from analysis.tabs.search import build_search_tab
|
||||
from analysis.tabs.browser import build_browser_tab
|
||||
from analysis.tabs.components import build_svd_components_tab
|
||||
from analysis.tabs.quiz import build_mp_quiz_tab
|
||||
|
||||
__all__ = [
|
||||
"build_compass_tab",
|
||||
"build_trajectories_tab",
|
||||
"build_search_tab",
|
||||
"build_browser_tab",
|
||||
"build_svd_components_tab",
|
||||
"build_mp_quiz_tab",
|
||||
]
|
||||
|
||||
+4
-66
@@ -1,10 +1,9 @@
|
||||
"""Parlement Explorer — Streamlit data analysis app.
|
||||
|
||||
Four tabs:
|
||||
Three tabs:
|
||||
1. Politiek Kompas — 2D scatter of MPs/parties, window slider
|
||||
2. Partij Trajectories — party centroid lines over time
|
||||
3. Motie Zoeken — text search + similarity lookup
|
||||
4. Motie Browser — sortable table + detail panel
|
||||
3. SVD Components — component themes, scree plot, party positions
|
||||
|
||||
Run with: streamlit run explorer.py
|
||||
|
||||
@@ -408,49 +407,6 @@ def load_motions_df(db_path: str) -> pd.DataFrame:
|
||||
return explorer_data.load_motions_df(db_path)
|
||||
|
||||
|
||||
def query_similar(
|
||||
db_path: str,
|
||||
source_motion_id: int,
|
||||
vector_type: str = "fused",
|
||||
top_k: int = 10,
|
||||
) -> pd.DataFrame:
|
||||
"""Return top-k similar motions from similarity_cache (read-only)."""
|
||||
return explorer_data.query_similar(db_path, source_motion_id, vector_type, top_k)
|
||||
|
||||
|
||||
def _window_to_dates(window_id: str) -> tuple[str, str]:
|
||||
"""Return (start_date, end_date) ISO strings for a given window_id."""
|
||||
return trajectory.window_to_dates(window_id)
|
||||
|
||||
|
||||
def build_compass_tab(*args, **kwargs):
|
||||
"""Build the Politiek Kompas tab."""
|
||||
from analysis.tabs.compass import build_compass_tab as _impl
|
||||
|
||||
return _impl(*args, **kwargs)
|
||||
|
||||
|
||||
def build_trajectories_tab(*args, **kwargs):
|
||||
"""Build the Partij Trajectories tab."""
|
||||
from analysis.tabs.trajectories import build_trajectories_tab as _impl
|
||||
|
||||
return _impl(*args, **kwargs)
|
||||
|
||||
|
||||
def build_search_tab(*args, **kwargs):
|
||||
"""Build the Motie Zoeken tab."""
|
||||
from analysis.tabs.search import build_search_tab as _impl
|
||||
|
||||
return _impl(*args, **kwargs)
|
||||
|
||||
|
||||
def build_browser_tab(*args, **kwargs):
|
||||
"""Build the Motie Browser tab."""
|
||||
from analysis.tabs.browser import build_browser_tab as _impl
|
||||
|
||||
return _impl(*args, **kwargs)
|
||||
|
||||
|
||||
def build_svd_components_tab(*args, **kwargs):
|
||||
"""Build the SVD Components tab."""
|
||||
from analysis.tabs.components import build_svd_components_tab as _impl
|
||||
@@ -476,24 +432,16 @@ def run_app() -> None:
|
||||
st.sidebar.title("Instellingen")
|
||||
db_path = "data/motions.db"
|
||||
window_size = "annual"
|
||||
show_rejected = st.sidebar.checkbox("Toon verworpen moties", value=False)
|
||||
|
||||
with st.sidebar.expander("ℹ️ Over", expanded=False):
|
||||
try:
|
||||
if _DUCKDB_AVAILABLE:
|
||||
con = duckdb.connect(database=db_path, read_only=True)
|
||||
n_motions = con.execute("SELECT COUNT(*) FROM motions").fetchone()[0]
|
||||
n_fused = con.execute(
|
||||
"SELECT COUNT(*) FROM fused_embeddings"
|
||||
).fetchone()[0]
|
||||
n_sim = con.execute("SELECT COUNT(*) FROM similarity_cache").fetchone()[
|
||||
0
|
||||
]
|
||||
con.close()
|
||||
st.markdown(
|
||||
f"**Moties:** {n_motions:,} \n"
|
||||
f"**Fused embeddings:** {n_fused:,} \n"
|
||||
f"**Similarity cache:** {n_sim:,}"
|
||||
f"**Vensters:** per jaar + huidig parlement"
|
||||
)
|
||||
else:
|
||||
st.warning(
|
||||
@@ -505,22 +453,16 @@ def run_app() -> None:
|
||||
tab_labels = [
|
||||
"🧭 Politiek Kompas",
|
||||
"📈 Trajectories",
|
||||
"🔍 Motie Zoeken",
|
||||
"📋 Motie Browser",
|
||||
"🔬 SVD Components",
|
||||
]
|
||||
|
||||
if hasattr(st, "tabs") and callable(getattr(st, "tabs")):
|
||||
tab1, tab2, tab3, tab4, tab5 = st.tabs(tab_labels)
|
||||
tab1, tab2, tab3 = st.tabs(tab_labels)
|
||||
with tab1:
|
||||
build_compass_tab(db_path, window_size)
|
||||
with tab2:
|
||||
build_trajectories_tab(db_path, window_size)
|
||||
with tab3:
|
||||
build_search_tab(db_path, show_rejected)
|
||||
with tab4:
|
||||
build_browser_tab(db_path, show_rejected)
|
||||
with tab5:
|
||||
build_svd_components_tab(db_path)
|
||||
else:
|
||||
selection = st.radio("Tab", tab_labels)
|
||||
@@ -528,10 +470,6 @@ def run_app() -> None:
|
||||
build_compass_tab(db_path, window_size)
|
||||
elif selection == tab_labels[1]:
|
||||
build_trajectories_tab(db_path, window_size)
|
||||
elif selection == tab_labels[2]:
|
||||
build_search_tab(db_path, show_rejected)
|
||||
elif selection == tab_labels[3]:
|
||||
build_browser_tab(db_path, show_rejected)
|
||||
else:
|
||||
build_svd_components_tab(db_path)
|
||||
|
||||
|
||||
@@ -27,8 +27,6 @@ class TestExplorerDecomposition:
|
||||
tabs = [
|
||||
("analysis/tabs/compass.py", "build_compass_tab"),
|
||||
("analysis/tabs/trajectories.py", "build_trajectories_tab"),
|
||||
("analysis/tabs/search.py", "build_search_tab"),
|
||||
("analysis/tabs/browser.py", "build_browser_tab"),
|
||||
("analysis/tabs/components.py", "build_svd_components_tab"),
|
||||
("analysis/tabs/quiz.py", "build_mp_quiz_tab"),
|
||||
]
|
||||
@@ -75,8 +73,6 @@ class TestExplorerDecomposition:
|
||||
tab_modules = [
|
||||
"analysis/tabs/compass.py",
|
||||
"analysis/tabs/trajectories.py",
|
||||
"analysis/tabs/search.py",
|
||||
"analysis/tabs/browser.py",
|
||||
"analysis/tabs/components.py",
|
||||
"analysis/tabs/quiz.py",
|
||||
"analysis/tabs/_rendering.py",
|
||||
|
||||
@@ -9,6 +9,5 @@ def test_explorer_importable():
|
||||
assert callable(mod.run_app)
|
||||
assert hasattr(mod, "load_positions")
|
||||
assert hasattr(mod, "load_motions_df")
|
||||
assert hasattr(mod, "query_similar")
|
||||
assert hasattr(mod, "build_compass_tab")
|
||||
assert hasattr(mod, "build_search_tab")
|
||||
assert hasattr(mod, "build_svd_components_tab")
|
||||
assert hasattr(mod, "build_mp_quiz_tab")
|
||||
|
||||
Reference in New Issue
Block a user