Simplify scale figure with accessible colors

This commit is contained in:
Armin
2026-08-14 12:38:03 +00:00
parent 1909da3720
commit 9f809bad1e
6 changed files with 31 additions and 69 deletions
+2 -13
View File
@@ -1,6 +1,6 @@
# Scale-example selection and interpretation
The scale examples are selected to make the two released dimensions substantively interpretable. They are illustrative reference cases rather than a representative sample or an independent validation of the posterior coordinates. Published party-history research supports the qualitative interpretation of the cases, not their exact estimated values.
The scale examples are selected to make the two released dimensions substantively interpretable without overloading the display. They are illustrative trajectories rather than a representative sample or an independent validation of the posterior coordinates. Published party-history research supports the qualitative interpretation of the cases, not their exact estimated values.
## Trajectory figure
@@ -12,15 +12,4 @@ The connected paths show recognizable changes across countries and political tra
All election-year posterior means in these windows form the connected paths. The labelled endpoints include 95% latent-position credible intervals. The manuscript uses published historical research to interpret the broad movements without treating the estimates as causal evidence.
## Two-dimensional landmarks
The standalone anchors cover low, middle and high regions of both scales and include cross-pressured combinations:
- German The Left: 2021 (PartyFacts 1545).
- German Christian Democratic Union: 2021 (PartyFacts 1375).
- Polish Law and Justice: 2019 (PartyFacts 1565).
- UK Conservative Party: 1979 (PartyFacts 1567).
- French National Front: 2022 (PartyFacts 433).
- US Republican Party: 2020 (PartyFacts 809).
Every anchor must match the requested party-year exactly. Horizontal and vertical bars show 95% latent-position credible intervals. The machine-readable plotting table retains every path observation and anchor.
The figure deliberately omits standalone party-year anchors. Colour-blind-safe colours distinguish the three paths, while redundant line types and point shapes preserve legibility in monochrome reproduction. Horizontal and vertical bars show 95% latent-position credible intervals at each labelled endpoint. The machine-readable plotting table retains every path observation.
+1 -1
View File
@@ -1,6 +1,6 @@
id,topic,input,output,status
1,country coverage,release v0 election-year panel,metadata/country_coverage_v0.csv,complete
2,historical scale anchors and trajectories,release v0 election-year panel,validation/figures/party_scale_examples.pdf,complete
2,historical party trajectories,release v0 election-year panel,validation/figures/party_scale_examples.pdf,complete
4,research workflow,documented source and release workflow,validation/figures/research_workflow.pdf,complete
5,party-blocked validation,guarded blocked fit with 82 parties and completed post-estimation extraction,validation/outputs/blocked_validation_summary.csv,complete_with_convergence_limitation
6,predictive coverage,production posterior run run_2026-06-12_09-34-03,validation/outputs/ppc/posterior_predictive_by_dimension_item.csv,complete
1 id topic input output status
2 1 country coverage release v0 election-year panel metadata/country_coverage_v0.csv complete
3 2 historical scale anchors and trajectories historical party trajectories release v0 election-year panel validation/figures/party_scale_examples.pdf complete
4 4 research workflow documented source and release workflow validation/figures/research_workflow.pdf complete
5 5 party-blocked validation guarded blocked fit with 82 parties and completed post-estimation extraction validation/outputs/blocked_validation_summary.csv complete_with_convergence_limitation
6 6 predictive coverage production posterior run run_2026-06-12_09-34-03 validation/outputs/ppc/posterior_predictive_by_dimension_item.csv complete
+1 -1
View File
@@ -20,7 +20,7 @@ The validation fit retains the production warmup length and four-chain design bu
## Reproduction Entry Points
- `plot_scale_examples.R`: historically anchored party paths and scale-reference cases generated from the released election-year panel.
- `plot_scale_examples.R`: three historically interpretable party paths generated from the released election-year panel.
- `run_postprocessing.R`: country coverage, scale examples, V-Party sensitivity and partially pooled source-support diagnostics.
- `validate_uncertainty.jl`: production-chain predictive coverage, calibration and source/item/country/decade breakdowns.
- `prepare_blocked_validation.jl`: deterministic party-blocked train/test construction.
Binary file not shown.
@@ -50,9 +50,3 @@
432,"Democratic Party","US",2014,"US Democrats","trajectory",FALSE,"",0.462867505375,0.326761075,0.602355425,0.389843067375,0.309037225,0.471238225,"both_direct_or_nearby"
432,"Democratic Party","US",2016,"US Democrats","trajectory",FALSE,"",0.388854405625,0.2650008,0.511855575,0.371516706875,0.296737875,0.446610025,"both_direct_or_nearby"
432,"Democratic Party","US",2020,"US Democrats","trajectory",TRUE,"US Democrats 2020",0.299892256625,0.1963003,0.410606025,0.3345769065,0.263694925,0.405684575,"both_direct_or_nearby"
1545,"The Left","DE",2021,"Standalone anchors","anchor",TRUE,"The Left 2021",0.05463340125125,0.0205853625,0.104672875,0.2266517688,0.13204575,0.336095325,"both_direct_or_nearby"
1375,"Christian Democratic Union","DE",2021,"Standalone anchors","anchor",TRUE,"CDU 2021",0.57714137175,0.45681705,0.69505505,0.536185121875,0.433751725,0.636189175,"text_only_direct_or_nearby"
1565,"Law and Justice","PL",2019,"Standalone anchors","anchor",TRUE,"PiS 2019",0.230162367175,0.159245575,0.300962375,0.841737028125,0.78973335,0.891444425,"both_direct_or_nearby"
1567,"Conservative Party","GB",1979,"Standalone anchors","anchor",TRUE,"UK Conservatives 1979",0.863733304625,0.78370345,0.932120225,0.58421918175,0.47261405,0.691922375,"both_direct_or_nearby"
433,"National Front","FR",2022,"Standalone anchors","anchor",TRUE,"French National Front 2022",0.524320955125,0.398589175,0.645052275,0.829604491,0.73907015,0.911430725,"both_direct_or_nearby"
809,"Republican Party","US",2020,"Standalone anchors","anchor",TRUE,"US Republicans 2020",0.8507495345,0.77742365,0.917357075,0.721311676375,0.65728435,0.78442835,"both_direct_or_nearby"
1 party_id party_name_english country year series display_role is_labelled label economic_lr economic_lr_q025 economic_lr_q975 galtan galtan_q025 galtan_q975 source_support_class
50 432 Democratic Party US 2014 US Democrats trajectory FALSE 0.462867505375 0.326761075 0.602355425 0.389843067375 0.309037225 0.471238225 both_direct_or_nearby
51 432 Democratic Party US 2016 US Democrats trajectory FALSE 0.388854405625 0.2650008 0.511855575 0.371516706875 0.296737875 0.446610025 both_direct_or_nearby
52 432 Democratic Party US 2020 US Democrats trajectory TRUE US Democrats 2020 0.299892256625 0.1963003 0.410606025 0.3345769065 0.263694925 0.405684575 both_direct_or_nearby
1545 The Left DE 2021 Standalone anchors anchor TRUE The Left 2021 0.05463340125125 0.0205853625 0.104672875 0.2266517688 0.13204575 0.336095325 both_direct_or_nearby
1375 Christian Democratic Union DE 2021 Standalone anchors anchor TRUE CDU 2021 0.57714137175 0.45681705 0.69505505 0.536185121875 0.433751725 0.636189175 text_only_direct_or_nearby
1565 Law and Justice PL 2019 Standalone anchors anchor TRUE PiS 2019 0.230162367175 0.159245575 0.300962375 0.841737028125 0.78973335 0.891444425 both_direct_or_nearby
1567 Conservative Party GB 1979 Standalone anchors anchor TRUE UK Conservatives 1979 0.863733304625 0.78370345 0.932120225 0.58421918175 0.47261405 0.691922375 both_direct_or_nearby
433 National Front FR 2022 Standalone anchors anchor TRUE French National Front 2022 0.524320955125 0.398589175 0.645052275 0.829604491 0.73907015 0.911430725 both_direct_or_nearby
809 Republican Party US 2020 Standalone anchors anchor TRUE US Republicans 2020 0.8507495345 0.77742365 0.917357075 0.721311676375 0.65728435 0.78442835 both_direct_or_nearby
+27 -48
View File
@@ -49,31 +49,13 @@ trajectory_rows <- lapply(seq_len(nrow(trajectory_spec)), function(i) {
})
trajectories <- do.call(rbind, trajectory_rows)
anchor_spec <- data.frame(
party_id = c(1545, 1375, 1565, 1567, 433, 809),
year = c(2021, 2021, 2019, 1979, 2022, 2020),
label = c(
"The Left 2021", "CDU 2021", "PiS 2019",
"UK Conservatives 1979", "French National Front 2022",
"US Republicans 2020"
)
)
anchors <- merge(anchor_spec, panel, by = c("party_id", "year"), all.x = TRUE, sort = FALSE)
if (anyNA(anchors$economic_lr) || anyNA(anchors$galtan)) {
stop("One or more declared scale anchors are absent from the release panel")
}
anchors$series <- "Standalone anchors"
anchors$display_role <- "anchor"
anchors$is_labelled <- TRUE
plot_columns <- c(
"party_id", "party_name_english", "country", "year", "series",
"display_role", "is_labelled", "label", "economic_lr",
"economic_lr_q025", "economic_lr_q975", "galtan", "galtan_q025",
"galtan_q975", "source_support_class"
)
plot_data <- rbind(trajectories[plot_columns], anchors[plot_columns])
plot_data <- trajectories[plot_columns]
write.csv(
plot_data,
file.path(output_dir, "party_scale_example_plot_data.csv"),
@@ -86,21 +68,15 @@ label_positions <- data.frame(
label = c(
"Fidesz 1990", "Fidesz 2022",
"Danish Social Democrats 2007", "Danish Social Democrats 2019",
"US Democrats 1944", "US Democrats 2020",
"The Left 2021", "CDU 2021", "PiS 2019",
"UK Conservatives 1979", "French National Front 2022",
"US Republicans 2020"
"US Democrats 1944", "US Democrats 2020"
),
plot_label = c(
"Fidesz\n1990", "Fidesz\n2022",
"Danish Social Democrats\n2007", "Danish Social Democrats\n2019",
"US Democrats\n1944", "US Democrats\n2020",
"The Left\n2021", "CDU\n2021", "PiS\n2019",
"UK Conservatives\n1979", "French National Front\n2022",
"US Republicans\n2020"
"US Democrats\n1944", "US Democrats\n2020"
),
label_x = c(.84, .36, .12, .33, .73, .36, .11, .65, .14, .84, .58, .88),
label_y = c(.36, .93, .32, .49, .33, .27, .16, .48, .93, .51, .91, .78)
label_x = c(.84, .36, .12, .33, .73, .36),
label_y = c(.36, .93, .32, .49, .33, .27)
)
labelled <- merge(labelled, label_positions, by = "label", all.x = TRUE, sort = FALSE)
if (anyNA(labelled$label_x) || anyNA(labelled$label_y)) {
@@ -113,39 +89,34 @@ trajectories$series <- factor(trajectories$series, levels = trajectory_levels)
p <- ggplot() +
geom_path(
data = trajectories,
aes(x = economic_lr, y = galtan, group = series, linetype = series),
colour = "grey25", linewidth = .7,
aes(x = economic_lr, y = galtan, group = series, colour = series, linetype = series),
linewidth = .85,
arrow = grid::arrow(type = "closed", length = grid::unit(.065, "inches"))
) +
geom_point(
data = trajectories,
aes(x = economic_lr, y = galtan),
colour = "grey35", size = 1.1
aes(x = economic_lr, y = galtan, colour = series, shape = series),
size = 1.4
) +
geom_errorbar(
data = labelled,
aes(x = economic_lr, ymin = galtan_q025, ymax = galtan_q975),
width = 0, colour = "grey45", alpha = .65
aes(x = economic_lr, ymin = galtan_q025, ymax = galtan_q975, colour = series),
width = 0, alpha = .75
) +
geom_errorbar(
data = labelled,
aes(y = galtan, xmin = economic_lr_q025, xmax = economic_lr_q975),
orientation = "y", width = 0, colour = "grey45", alpha = .65
aes(y = galtan, xmin = economic_lr_q025, xmax = economic_lr_q975, colour = series),
orientation = "y", width = 0, alpha = .75
) +
geom_point(
data = anchors,
aes(x = economic_lr, y = galtan),
shape = 21, fill = "white", colour = "black", size = 2.5, stroke = .7
) +
geom_point(
data = labelled[labelled$display_role == "trajectory", ],
aes(x = economic_lr, y = galtan),
shape = 16, colour = "black", size = 2.1
data = labelled,
aes(x = economic_lr, y = galtan, colour = series, shape = series),
size = 2.4
) +
geom_segment(
data = labelled,
aes(x = economic_lr, y = galtan, xend = label_x, yend = label_y),
colour = "grey55", linewidth = .25
aes(x = economic_lr, y = galtan, xend = label_x, yend = label_y, colour = series),
linewidth = .3, show.legend = FALSE
) +
geom_text(
data = labelled,
@@ -155,12 +126,20 @@ p <- ggplot() +
scale_linetype_manual(
values = c("Fidesz" = "solid", "Danish Social Democrats" = "dashed", "US Democrats" = "dotdash")
) +
scale_colour_manual(
values = c("Fidesz" = "#D55E00", "Danish Social Democrats" = "#009E73", "US Democrats" = "#0072B2")
) +
scale_shape_manual(
values = c("Fidesz" = 16, "Danish Social Democrats" = 17, "US Democrats" = 15)
) +
scale_x_continuous(limits = c(0, 1), breaks = c(0, .25, .5, .75, 1)) +
scale_y_continuous(limits = c(0, 1), breaks = c(0, .25, .5, .75, 1)) +
labs(
x = "Economic: left (0) to right (1)",
y = "Cultural: cosmopolitan (0) to traditionalist (1)",
linetype = "Election-year path"
colour = "Election-year path",
linetype = "Election-year path",
shape = "Election-year path"
) +
theme_minimal(base_size = 9) +
theme(