partisan-disease-simulator / R /plot_utils.R
chrissoria's picture
Fix invisible lines in plots and Total infected percentage bug
edefa8f
library(cowplot)
library(ggplot2)
# =============================================================================
# CENTRALIZED COLOR PALETTE (WCAG AA Accessible)
# =============================================================================
#' Partisan color palette for consistent, accessible visualization
partisan_colors <- list(
republican = "#D32F2F", # Accessible red
democrat = "#1976D2", # Accessible blue
independent = "#388E3C", # Accessible green
total = "#424242", # Dark gray for totals
reference = "#757575", # Medium gray for reference lines
cautious = "#7B1FA2" # Purple for best-case/cautious model
)
#' Get named vector of partisan colors for ggplot scale_color_manual
#' @return Named character vector
get_partisan_colors <- function() {
c(
"Republican" = partisan_colors$republican,
"Democrat" = partisan_colors$democrat,
"Independent" = partisan_colors$independent,
"Republicans" = partisan_colors$republican,
"Democrats" = partisan_colors$democrat,
"Independents" = partisan_colors$independent,
"Total" = partisan_colors$total,
"Republicans Infected" = partisan_colors$republican,
"Democrats Infected" = partisan_colors$democrat,
"Independents Infected" = partisan_colors$independent
)
}
#' Get named vector for line types
#' @return Named character vector
get_model_linetypes <- function() {
c(
"Reference Model" = "dashed",
"Current Model" = "solid",
"Best Case Model" = "dotted",
"Homogenous" = "dashed"
)
}
# =============================================================================
# CONSISTENT PLOT THEME
# =============================================================================
#' Custom theme for partisan disease plots
#'
#' A clean, professional theme with subtle grid lines for readability
#'
#' @param base_size Base font size (default 14)
#' @param title_size Title font size (default 16)
#' @return ggplot2 theme object
theme_partisan <- function(base_size = 14, title_size = 16) {
theme_cowplot(font_size = base_size) +
theme(
# Title and subtitle
plot.title = element_text(
size = title_size,
face = "bold",
color = "#424242",
margin = margin(b = 8)
),
plot.subtitle = element_text(
size = base_size - 1,
color = "#616161",
margin = margin(b = 8),
lineheight = 1.3
),
# Axis styling
axis.title = element_text(size = base_size - 1, color = "#424242"),
axis.text = element_text(size = base_size - 2, color = "#616161"),
axis.line = element_line(color = "#BDBDBD", size = 0.5),
# Subtle grid for readability
panel.grid.major.y = element_line(color = "#EEEEEE", size = 0.3),
panel.grid.major.x = element_blank(),
panel.grid.minor = element_blank(),
# Legend styling
legend.background = element_rect(fill = "white", color = NA),
legend.title = element_text(size = base_size - 1, face = "bold"),
legend.text = element_text(size = base_size - 2),
# Overall plot styling
plot.background = element_rect(fill = "white", color = NA),
panel.background = element_rect(fill = "#FAFAFA", color = NA),
# Margins
plot.margin = margin(t = 10, r = 10, b = 10, l = 10)
)
}
# =============================================================================
# UTILITY FUNCTIONS
# =============================================================================
#' Get legend from a ggplot object
#'
#' @param plot ggplot object
#' @param legend Optional legend identifier
#' @return Legend grob
get_legend_35 <- function(plot, legend = NULL) {
# Use cowplot's get_legend as fallback
tryCatch({
leg <- cowplot::get_legend(plot)
return(leg)
}, error = function(e) {
return(NULL)
})
}