fix(overton): reframe verdict and migration as gateway domain
- Verdict now says 'window widened' (not 'did not shift') — centrist support surged for right-wing motions while staying flat for left-wing - Migration reframed from 'one exception' to 'gateway domain' — where acceptance expanded most genuinely and right-wing parties learned frames they applied elsewhere - Explorer Overton tab: added migration gateway section with pre/post metrics, full motion text (no truncation), 100-motion browser - Explorer Kompas tab: updated Overton context to lead with the shift - Explorer Trajectories tab: Dutch-language Overton annotation - Synthesis, QMD, HTML report, STATUS.md all updated consistently
This commit is contained in:
@@ -185,13 +185,16 @@ def build_compass_tab(db_path: str, window_size: str) -> None:
|
||||
|
||||
with st.expander("Overton Window Context"):
|
||||
st.markdown(
|
||||
"Het SVD-kompas visualiseert direct de dynamiek achter de "
|
||||
"Overton-verschuiving in de Tweede Kamer.\n\n"
|
||||
"**Centristische partijen** (D66, CDA, CU, NSC) zijn op **beide assen naar"
|
||||
"Het SVD-kompas visualiseert de dynamiek achter de "
|
||||
"**verbreding van het Overton-venster** in de Tweede Kamer.\n\n"
|
||||
"Centristische steun voor rechtse moties steeg van 25% naar 51% na 2024, "
|
||||
"terwijl steun voor linkse moties gelijk bleef. Het venster verschoof — "
|
||||
"meer rechtse standpunten werden acceptabel.\n\n"
|
||||
"Maar: **centristische partijen** (D66, CDA, CU, NSC) zijn op **beide assen naar"
|
||||
" links** verschoven, terwijl rechtse partijen stabiel bleven. Dit patroon"
|
||||
' van "acceptatie zonder conversie" betekent dat centristen meer met'
|
||||
" rechtse moties meestemmen terwijl ze ideologisch verder van rechts af"
|
||||
" komen te staan.\n\n"
|
||||
' van "acceptatie zonder conversie" betekent dat rechtse partijen mildere'
|
||||
" moties gingen indienen, en centristen daardoor vaker konden meestemmen — "
|
||||
"zonder dat ze ideologisch naar rechts opschoven.\n\n"
|
||||
"[Lees de volledige analyse](../reports/overton_window/overton_window.qmd)\n\n"
|
||||
"Probeer de **Stemwijzer-quiz** om te zien welke MP bij jouw standpunten past."
|
||||
)
|
||||
|
||||
@@ -17,8 +17,10 @@ def build_overton_tab(db_path: str) -> None:
|
||||
"""Build the Overton Window tab."""
|
||||
st.subheader("Overton Window Analyse")
|
||||
st.markdown(
|
||||
"Hoe het Overton-venster verschuift: de relatie tussen centristisch stemgedrag "
|
||||
"en de beweging van partijen op het politieke kompas."
|
||||
"Het Overton-venster **verbreedde** na 2024: centristische steun voor rechtse "
|
||||
"moties steeg van 25% naar 51%, terwijl steun voor linkse moties gelijk bleef. "
|
||||
"Rechtse partijen dienden mildere moties in, waardoor centristen vaker konden "
|
||||
"meestemmen — zonder ideologisch naar rechts op te schuiven."
|
||||
)
|
||||
|
||||
try:
|
||||
@@ -44,6 +46,7 @@ def build_overton_tab(db_path: str) -> None:
|
||||
try:
|
||||
_render_centrist_support_chart(con)
|
||||
_render_summary_stats(con)
|
||||
_render_migration_gateway(con)
|
||||
_render_motion_browser(con)
|
||||
_render_explore_further()
|
||||
except Exception as e:
|
||||
@@ -135,23 +138,70 @@ def _render_summary_stats(con: duckdb.DuckDBPyConnection) -> None:
|
||||
col4.metric("2D correlation r", "0.47")
|
||||
|
||||
|
||||
def _render_migration_gateway(con: duckdb.DuckDBPyConnection) -> None:
|
||||
st.subheader("Migratie: de gateway-domein")
|
||||
st.markdown(
|
||||
"Migratie is waar de Overton-verschuiving het meest echt is — en waar "
|
||||
"rechtse partijen de frames leerden die ze later op andere domeinen toepasten."
|
||||
)
|
||||
|
||||
df = con.execute("""
|
||||
SELECT
|
||||
CASE WHEN year < 2024 THEN 'Pre-2024' ELSE 'Post-2024' END as period,
|
||||
AVG(centrist_support_strict) as cs_strict,
|
||||
COUNT(*) as n_motions
|
||||
FROM right_wing_motions
|
||||
WHERE classified = TRUE
|
||||
AND year >= 2016
|
||||
AND category IN ('asiel/vreemdelingen', 'asiel')
|
||||
GROUP BY period
|
||||
ORDER BY period
|
||||
""").fetchdf()
|
||||
|
||||
if df.empty or len(df) < 2:
|
||||
return
|
||||
|
||||
pre = df[df["period"] == "Pre-2024"].iloc[0]
|
||||
post = df[df["period"] == "Post-2024"].iloc[0]
|
||||
|
||||
col1, col2, col3, col4 = st.columns(4)
|
||||
col1.metric("Pre-2024 CS (migratie)", f"{pre['cs_strict']:.3f}")
|
||||
col2.metric("Post-2024 CS (migratie)", f"{post['cs_strict']:.3f}")
|
||||
col3.metric("Shift", f"{post['cs_strict'] - pre['cs_strict']:+.3f}")
|
||||
col4.metric("Moties", f"{int(pre['n_motions'] + post['n_motions'])}")
|
||||
|
||||
st.caption(
|
||||
"Ter vergelijking: niet-migratie moties gingen van 0.276 naar 0.481 (+0.205). "
|
||||
"Migratie steeg meer dan twee keer zo hard (+0.216), terwijl de materiële impact "
|
||||
"nauwelijks daalde. CDA en ChristenUnie verdubbelden hun migratie-steun "
|
||||
"(18%→40%, 10%→30%)."
|
||||
)
|
||||
|
||||
|
||||
def _render_motion_browser(con: duckdb.DuckDBPyConnection) -> None:
|
||||
st.subheader("Rechtse Moties Browser")
|
||||
|
||||
df = con.execute("""
|
||||
SELECT year, title, centrist_support_strict, category
|
||||
FROM right_wing_motions
|
||||
WHERE classified = TRUE
|
||||
ORDER BY centrist_support_strict DESC
|
||||
LIMIT 50
|
||||
SELECT r.year, r.title, m.text, r.centrist_support_strict, r.category
|
||||
FROM right_wing_motions r
|
||||
LEFT JOIN motions m ON r.motion_id = m.id
|
||||
WHERE r.classified = TRUE
|
||||
ORDER BY r.centrist_support_strict DESC
|
||||
LIMIT 100
|
||||
""").fetchdf()
|
||||
|
||||
if df.empty:
|
||||
st.info("Geen rechtse moties gevonden.")
|
||||
return
|
||||
|
||||
df["title"] = df["title"].str.slice(0, 80)
|
||||
st.dataframe(df, use_container_width=True)
|
||||
df = df.rename(columns={
|
||||
"year": "Jaar",
|
||||
"title": "Titel",
|
||||
"text": "Motietekst",
|
||||
"centrist_support_strict": "Centrist Support",
|
||||
"category": "Categorie",
|
||||
})
|
||||
st.dataframe(df, use_container_width=True, height=600)
|
||||
|
||||
|
||||
def _render_explore_further() -> None:
|
||||
|
||||
@@ -667,8 +667,10 @@ def build_trajectories_tab(db_path: str, window_size: str) -> None:
|
||||
try:
|
||||
st.plotly_chart(fig, use_container_width=True)
|
||||
st.info(
|
||||
"**Overton shift:** centrist support for right-wing motions surged "
|
||||
"after PVV's Nov 2023 election win."
|
||||
"**Overton-venster verbreed:** na PVV's verkiezingsoverwinning (nov 2023) "
|
||||
"steeg centristische steun voor rechtse moties van 25% naar 51%, "
|
||||
"terwijl steun voor linkse moties gelijk bleef. "
|
||||
"Rechtse partijen matigden hun moties, centristen stemden vaker voor."
|
||||
)
|
||||
except Exception as e:
|
||||
st.error(f"Trajectories rendering failed: {e}")
|
||||
|
||||
Reference in New Issue
Block a user