{"spec_id":"area-stacked-confidence","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' area-stacked-confidence: Stacked Area Chart with Confidence Bands\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 87/100 | Created: 2026-05-18\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(ragg)\n\nset.seed(42)\n\n# --- Theme tokens -----------------------------------------------------------\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nELEVATED_BG <- if (THEME == \"light\") \"#FFFDF6\" else \"#242420\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\n\nIMPRINT   <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\",\n                 \"#AE3030\", \"#2ABCCD\", \"#954477\")\n\n# --- Data -------------------------------------------------------------------\n# Quarterly energy consumption forecast by source with confidence bands\nquarters <- 1:20\nsources_order <- c(\"Solar\", \"Wind\", \"Hydro\", \"Battery\")\n\ndf_base <- expand.grid(\n  quarter = quarters,\n  source = factor(sources_order, levels = sources_order)\n) %>%\n  arrange(quarter, source)\n\n# Generate central values and confidence bands\ndf_data <- df_base %>%\n  mutate(\n    base = case_when(\n      source == \"Solar\" ~ 800 + quarter * 50 + rnorm(n(), 0, 30),\n      source == \"Wind\" ~ 1200 + quarter * 30 + rnorm(n(), 0, 40),\n      source == \"Hydro\" ~ 600 - quarter * 10 + rnorm(n(), 0, 25),\n      source == \"Battery\" ~ 200 + quarter * 15 + rnorm(n(), 0, 15)\n    ),\n    # Confidence bands (uncertainty increases over forecast horizon)\n    uncertainty = case_when(\n      source == \"Solar\" ~ 50 + quarter * 3,\n      source == \"Wind\" ~ 60 + quarter * 4,\n      source == \"Hydro\" ~ 40 + quarter * 2,\n      source == \"Battery\" ~ 30 + quarter * 2\n    ),\n    value = pmax(base, 100),  # Ensure positive values\n    value_lower = pmax(value - uncertainty, 50),\n    value_upper = value + uncertainty\n  ) %>%\n  select(quarter, source, value, value_lower, value_upper)\n\n# Calculate cumulative stacked values\ndf_plot <- df_data %>%\n  arrange(quarter, source) %>%\n  group_by(quarter) %>%\n  mutate(\n    # Cumulative sum for stacking\n    prev_cumsum = lag(cumsum(value), default = 0),\n    y_base = prev_cumsum,\n    y_center = y_base + value,\n    y_lower = y_base + value_lower,\n    y_upper = y_base + value_upper\n  ) %>%\n  ungroup() %>%\n  arrange(quarter, source)\n\n# --- Plot -------------------------------------------------------------------\nanyplot_theme <- theme_minimal(base_size = 14) +\n  theme(\n    plot.background   = element_rect(fill = PAGE_BG, color = PAGE_BG),\n    panel.background  = element_rect(fill = PAGE_BG, color = NA),\n    panel.grid.major  = element_line(color = INK_SOFT, linewidth = 0.2),\n    panel.grid.minor  = element_blank(),\n    axis.title        = element_text(color = INK, size = 20),\n    axis.text         = element_text(color = INK_SOFT, size = 16),\n    plot.title        = element_text(color = INK, size = 24, face = \"bold\"),\n    legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT),\n    legend.text       = element_text(color = INK_SOFT, size = 16),\n    legend.title      = element_text(color = INK, size = 18)\n  )\n\np <- ggplot(df_plot, aes(x = quarter, fill = source, color = source)) +\n  # Confidence bands (lighter, more transparent)\n  geom_ribbon(aes(ymin = y_lower, ymax = y_upper), alpha = 0.2, color = NA) +\n  # Central stacked areas\n  geom_area(aes(y = y_center), alpha = 0.7, color = NA) +\n  scale_fill_manual(values = IMPRINT[1:4]) +\n  scale_color_manual(values = IMPRINT[1:4]) +\n  labs(\n    title = \"area-stacked-confidence · R · ggplot2 · anyplot.ai\",\n    x = \"Quarter\",\n    y = \"Energy (MWh)\",\n    fill = \"Source\"\n  ) +\n  anyplot_theme +\n  theme(\n    legend.position = \"top\",\n    legend.direction = \"horizontal\"\n  ) +\n  guides(color = \"none\")\n\n# --- Save -------------------------------------------------------------------\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 16,\n  height   = 9,\n  units    = \"in\",\n  dpi      = 300\n)\n"}