{"spec_id":"bar-stacked","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' bar-stacked: Stacked Bar Chart\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 92/100 | Created: 2026-09-02\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(ragg)\nlibrary(scales)\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\n# Imprint categorical palette — first series is always brand green\nIMPRINT_PALETTE <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\",\n                     \"#AE3030\", \"#2ABCCD\", \"#954477\", \"#99B314\")\n\n# --- Data -----------------------------------------------------------------\n# Monthly department budget breakdown, in thousands of dollars.\ndepartment_levels   <- c(\"Engineering\", \"Sales\", \"Marketing\", \"Support\")\ndepartment_baseline <- c(Engineering = 120, Sales = 80, Marketing = 50, Support = 40)\n\nexpense_df <- tibble::tibble(\n  month = rep(factor(month.abb[1:6], levels = month.abb[1:6]), times = length(department_levels)),\n  department = factor(rep(department_levels, each = 6), levels = department_levels),\n  expense = as.vector(sapply(department_baseline, function(base) {\n    pmax(round(base + rnorm(6, mean = 0, sd = base * 0.12)), 5)\n  }))\n)\n\ntotals_df <- expense_df %>%\n  group_by(month) %>%\n  summarise(total = sum(expense), .groups = \"drop\")\n\n# --- Plot -------------------------------------------------------------------\np <- ggplot(expense_df, aes(x = month, y = expense, fill = department)) +\n  geom_col(position = \"stack\", width = 0.65, color = PAGE_BG, linewidth = 0.3) +\n  geom_text(\n    aes(label = dollar(expense, prefix = \"$\", suffix = \"K\")),\n    position = position_stack(vjust = 0.5),\n    size = 2.6,\n    fontface = \"bold\",\n    color = \"#FFFFFF\"\n  ) +\n  geom_text(\n    data = totals_df,\n    aes(x = month, y = total, label = dollar(total, prefix = \"$\", suffix = \"K\")),\n    inherit.aes = FALSE,\n    vjust = -0.6,\n    size = 3.2,\n    color = INK\n  ) +\n  scale_fill_manual(values = IMPRINT_PALETTE[1:4], name = \"Department\") +\n  scale_y_continuous(\n    labels = label_dollar(prefix = \"$\", suffix = \"K\"),\n    expand = expansion(mult = c(0, 0.12))\n  ) +\n  labs(\n    title = \"bar-stacked · r · ggplot2 · anyplot.ai\",\n    x = \"Month\",\n    y = \"Expense ($K)\"\n  ) +\n  theme_minimal(base_size = 8) +\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.x = element_blank(),\n    panel.grid.minor   = element_blank(),\n    panel.grid.major.y = element_line(color = INK, linewidth = 0.25),\n    axis.ticks         = element_blank(),\n    axis.title         = element_text(color = INK, size = 10),\n    axis.text          = element_text(color = INK_SOFT, size = 8),\n    plot.title         = element_text(color = INK, size = 12),\n    legend.background  = element_rect(fill = ELEVATED_BG, color = INK_SOFT),\n    legend.text        = element_text(color = INK_SOFT, size = 8),\n    legend.title       = element_text(color = INK, size = 10),\n    legend.position    = \"right\"\n  )\n\n# --- Save -------------------------------------------------------------------\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 8,\n  height   = 4.5,\n  units    = \"in\",\n  dpi      = 400\n)\n"}