fix: add semantic left_pole/right_pole labels to SVD axes

main
Sven Geboers 4 weeks ago
parent f775e41c96
commit bce0ed56de
  1. 24
      analysis/config.py
  2. 24
      explorer.py

@ -78,8 +78,10 @@ SVD_THEMES: dict[int, dict[str, str]] = {
"klimaatsamenwerking. GroenLinks-PvdA, SP, PvdD en Volt scoren negatief. "
"Deze as weerspiegelt de coalitie-oppositie dynamiek."
),
"positive_pole": "Kabinetsbeleid: PVV, VVD, NSC, BBB, JA21 — defensie en restricties",
"negative_pole": "Oppositiebeleid: GroenLinks-PvdA, SP, PvdD, Volt, DENK — zorg en multilateraal",
"positive_pole": "Rechts: PVV, VVD, NSC, BBB, JA21 — kabinetsbeleid, defensie en restricties",
"negative_pole": "Links: GroenLinks-PvdA, SP, PvdD, Volt, DENK — oppositie, zorg en multilateraal",
"left_pole": "Links: GroenLinks-PvdA, SP, PvdD, Volt, DENK — oppositie, zorg en multilateraal",
"right_pole": "Rechts: PVV, VVD, NSC, BBB, JA21 — kabinetsbeleid, defensie en restricties",
"flip": False,
},
2: {
@ -95,6 +97,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "PVV en FVD — soevereiniteit en anti-establishment",
"negative_pole": "Overige partijen: VVD, CDA, SGP, ChristenUnie, GroenLinks-PvdA, D66, Volt, BBB",
"left_pole": "Overige partijen: VVD, CDA, SGP, ChristenUnie, GroenLinks-PvdA, D66, Volt, BBB",
"right_pole": "PVV en FVD — soevereiniteit en anti-establishment",
"flip": False,
},
3: {
@ -112,6 +116,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Pro-verzorgingsstaat: SP, PvdD, GroenLinks-PvdA (anti-bezuinigingen)",
"negative_pole": "Marktliberaal en fiscaal conservatief: VVD, D66, CDA, SGP, BBB",
"left_pole": "Marktliberaal en fiscaal conservatief: VVD, D66, CDA, SGP, BBB",
"right_pole": "Pro-verzorgingsstaat: SP, PvdD, GroenLinks-PvdA (anti-bezuinigingen)",
"flip": True,
},
4: {
@ -127,6 +133,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Mainstreampartijen: D66, CDA, VVD, PVV, GL-PvdA, SP, Volt, 50PLUS — breedgedragen moties",
"negative_pole": "FVD en DENK: oppositieposities buiten de mainstream",
"left_pole": "FVD en DENK: oppositieposities buiten de mainstream",
"right_pole": "Mainstreampartijen: D66, CDA, VVD, PVV, GL-PvdA, SP, Volt, 50PLUS — breedgedragen moties",
"flip": True,
},
5: {
@ -143,6 +151,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Christelijk-sociaal: ChristenUnie, SGP, CDA, NSC — gemeenschap en vrijwilligers",
"negative_pole": "Progressief-individueel: SP, VVD, GL-PvdA, PvdD, Volt — individuele rechten",
"left_pole": "Progressief-individueel: SP, VVD, GL-PvdA, PvdD, Volt — individuele rechten",
"right_pole": "Christelijk-sociaal: ChristenUnie, SGP, CDA, NSC — gemeenschap en vrijwilligers",
"flip": False,
},
6: {
@ -159,6 +169,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Restrictief migratiebeleid: PVV, JA21, BBB, CDA, ChristenUnie, VVD, SGP, FVD, DENK",
"negative_pole": "Progressieve inclusie: SP, PvdD, D66, GL-PvdA, Volt — klimaat en diversiteit",
"left_pole": "Progressieve inclusie: SP, PvdD, D66, GL-PvdA, Volt — klimaat en diversiteit",
"right_pole": "Restrictief migratiebeleid: PVV, JA21, BBB, CDA, ChristenUnie, VVD, SGP, FVD, DENK",
"flip": False,
},
7: {
@ -177,6 +189,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Praktisch-bestuurlijk: ChristenUnie, Volt, SGP, DENK, SP",
"negative_pole": "Ideologisch-principieel: GroenLinks-PvdA, VVD, FVD, JA21",
"left_pole": "Ideologisch-principieel: GroenLinks-PvdA, VVD, FVD, JA21",
"right_pole": "Praktisch-bestuurlijk: ChristenUnie, Volt, SGP, DENK, SP",
"flip": True,
},
8: {
@ -194,6 +208,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Onderwijs en volksgezondheid: BBB, SGP, JA21 — vaccinatie, profielkeuze, woningbouw",
"negative_pole": "Zorg en toegankelijkheid: SP, DENK, PvdD, Volt — coronaonderzoek, energie, basispakket",
"left_pole": "Zorg en toegankelijkheid: SP, DENK, PvdD, Volt — coronaonderzoek, energie, basispakket",
"right_pole": "Onderwijs en volksgezondheid: BBB, SGP, JA21 — vaccinatie, profielkeuze, woningbouw",
"flip": False,
},
9: {
@ -212,6 +228,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Pragmatisch-bestuurlijk: SGP, ChristenUnie, DENK, SP — concrete oplossingen",
"negative_pole": "Systeemhervorming: D66, JA21, PVV — idealistische beleidsposities",
"left_pole": "Systeemhervorming: D66, JA21, PVV — idealistische beleidsposities",
"right_pole": "Pragmatisch-bestuurlijk: SGP, ChristenUnie, DENK, SP — concrete oplossingen",
"flip": True,
},
10: {
@ -230,6 +248,8 @@ SVD_THEMES: dict[int, dict[str, str]] = {
),
"positive_pole": "Kritisch op overheidsbemoeienis: DENK, SP, PvdD — minder inspectielast en lastenverlichting",
"negative_pole": "Pro-regulering: GroenLinks-PvdA, CDA, SGP — veiligheid, naleving en handhaving",
"left_pole": "Pro-regulering: GroenLinks-PvdA, CDA, SGP — veiligheid, naleving en handhaving",
"right_pole": "Kritisch op overheidsbemoeienis: DENK, SP, PvdD — minder inspectielast en lastenverlichting",
"flip": True,
},
}

@ -966,8 +966,8 @@ def _build_party_axis_figure(
pos_pole = theme.get("positive_pole", "")
neg_pole = theme.get("negative_pole", "")
left_label = pos_pole if flip else neg_pole
right_label = neg_pole if flip else pos_pole
left_label = theme.get("left_pole", pos_pole if flip else neg_pole)
right_label = theme.get("right_pole", neg_pole if flip else pos_pole)
fig.update_layout(
height=160,
@ -1086,8 +1086,8 @@ def _render_party_axis_chart_1d(
# Determine pole labels based on flip
pos_pole = theme.get("positive_pole", "")
neg_pole = theme.get("negative_pole", "")
left_label = pos_pole if flip else neg_pole
right_label = neg_pole if flip else pos_pole
left_label = theme.get("left_pole", pos_pole if flip else neg_pole)
right_label = theme.get("right_pole", neg_pole if flip else pos_pole)
# Update layout with same format as components 1-2
fig.update_layout(
@ -1253,8 +1253,8 @@ def _render_svd_time_trajectory(
neg_pole = theme.get("negative_pole", "")
# Use the theme's flip value (computed from current_parliament) for label orientation
reference_flip = theme.get("flip", False)
left_label = pos_pole if reference_flip else neg_pole
right_label = neg_pole if reference_flip else pos_pole
left_label = theme.get("left_pole", pos_pole if reference_flip else neg_pole)
right_label = theme.get("right_pole", neg_pole if reference_flip else pos_pole)
# Y-axis labels
y_labels = {}
@ -2806,8 +2806,16 @@ def build_svd_components_tab(db_path: str) -> None:
pos_pole = theme.get("positive_pole", "") if theme else ""
neg_pole = theme.get("negative_pole", "") if theme else ""
# Determine which pole goes left (progressive) and which goes right
if flip:
# Use semantic left/right pole labels if available, otherwise compute from flip
semantic_left = theme.get("left_pole") if theme else None
semantic_right = theme.get("right_pole") if theme else None
if semantic_left and semantic_right:
left_pole, right_pole = semantic_left, semantic_right
left_motions, right_motions = (
(pos_motions, neg_motions) if flip else (neg_motions, pos_motions)
)
left_arrow, right_arrow = ("", "") if flip else ("", "")
elif flip:
left_pole, right_pole = pos_pole, neg_pole
left_motions, right_motions = pos_motions, neg_motions
left_arrow, right_arrow = "", ""

Loading…
Cancel
Save