fix: use CANONICAL_LEFT/RIGHT in compass PCA for consistency with SVD components tab
Previously the compass (political_axis.py) used hardcoded party sets that excluded Volt and PvdD, while the SVD components tab (svd_labels.py) used CANONICAL_LEFT/RIGHT which includes them. This caused inconsistencies in axis orientation where Volt appeared most left on the compass but PvdD appeared most left in the SVD components visualization. Changes: - Import CANONICAL_LEFT/RIGHT from config in political_axis.py - Replace hardcoded party sets with CANONICAL_LEFT/RIGHT for axis orientation - Update tests to match new SVD_THEMES labels
This commit is contained in:
+20
-35
@@ -1,13 +1,13 @@
|
||||
"""political_axis.py — Project MP SVD vectors onto an ideological axis.
|
||||
|
||||
Two modes:
|
||||
1. PCA mode (default): compute the first principal component of all MP SVD
|
||||
vectors for a window and project each MP onto it. The sign is arbitrary
|
||||
but consistent within a window.
|
||||
1. PCA mode (default): compute the first principal component of all MP SVD
|
||||
vectors for a window and project each MP onto it. The sign is arbitrary
|
||||
but consistent within a window.
|
||||
|
||||
2. Anchor mode: define the axis as the vector from the centroid of
|
||||
``left_parties`` to the centroid of ``right_parties``. Project all MPs
|
||||
onto this normalised anchor axis.
|
||||
2. Anchor mode: define the axis as the vector from the centroid of
|
||||
``left_parties`` to the centroid of ``right_parties``. Project all MPs
|
||||
onto this normalised anchor axis.
|
||||
|
||||
Both modes return a dict mapping mp_name → scalar score for the given window.
|
||||
"""
|
||||
@@ -24,6 +24,13 @@ try:
|
||||
except Exception: # pragma: no cover - allow importing module in lightweight test envs
|
||||
duckdb = None # type: ignore
|
||||
|
||||
# Import canonical party sets from config for consistent orientation with SVD components tab
|
||||
try:
|
||||
from .config import CANONICAL_LEFT, CANONICAL_RIGHT
|
||||
except Exception: # pragma: no cover - fallback for test environments
|
||||
CANONICAL_LEFT: frozenset = frozenset()
|
||||
CANONICAL_RIGHT: frozenset = frozenset()
|
||||
|
||||
_logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
@@ -262,35 +269,13 @@ def compute_2d_axes(
|
||||
}
|
||||
|
||||
# Canonical party sets used for axis orientation (global and per-window).
|
||||
# Defined outside the try-block so they're always in scope.
|
||||
right_parties = {
|
||||
"PVV",
|
||||
"VVD",
|
||||
"FVD",
|
||||
"BBB",
|
||||
"JA21",
|
||||
"Nieuw Sociaal Contract",
|
||||
}
|
||||
left_parties = {"SP", "PvdA", "GL", "GroenLinks", "GroenLinks-PvdA", "DENK"}
|
||||
cons_parties = {
|
||||
"PVV",
|
||||
"VVD",
|
||||
"FVD",
|
||||
"CDA",
|
||||
"SGP",
|
||||
"BBB",
|
||||
"JA21",
|
||||
"Nieuw Sociaal Contract",
|
||||
}
|
||||
prog_parties = {
|
||||
"GL",
|
||||
"GroenLinks",
|
||||
"PvdA",
|
||||
"PvdD",
|
||||
"SP",
|
||||
"GroenLinks-PvdA",
|
||||
"DENK",
|
||||
}
|
||||
# Use CANONICAL_LEFT/RIGHT from config for consistency with SVD components tab.
|
||||
# X-axis: CANONICAL_RIGHT (right) vs CANONICAL_LEFT (left)
|
||||
# Y-axis: CANONICAL_LEFT (progressive) vs cons_parties (conservative)
|
||||
right_parties = CANONICAL_RIGHT
|
||||
left_parties = CANONICAL_LEFT
|
||||
cons_parties = CANONICAL_RIGHT # Conservative = right-leaning parties
|
||||
prog_parties = CANONICAL_LEFT # Progressive = left-leaning parties
|
||||
|
||||
# Ensure consistent left/right and progressive/conservative orientation
|
||||
# by checking canonical party centroids and flipping axis signs if needed.
|
||||
|
||||
Reference in New Issue
Block a user