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) }) }