{"spec_id":"bar-error","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' bar-error: Bar Chart with Error Bars\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 89/100 | Created: 2026-09-02\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(ragg)\n\nset.seed(42)\n\n# --- Theme tokens -------------------------------------------------------\nTHEME    <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG  <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nINK      <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\nBRAND    <- \"#009E73\" # Imprint palette position 1 — always first series\n\n# --- Data -----------------------------------------------------------------\n# Simulated field trial: crop yield (tons/hectare) across fertilizer\n# treatments, 8 replicate plots per treatment.\ntreatments <- c(\"Control\", \"Nitrogen\", \"Phosphorus\", \"Potassium\", \"NPK Mix\", \"Compost\")\ntrue_means <- c(3.2, 5.8, 4.6, 4.9, 7.4, 6.1)\ntrue_sds <- c(0.5, 0.7, 0.6, 0.55, 0.65, 0.6)\nn_reps <- 8\n\nreplicate_yields <- bind_rows(lapply(seq_along(treatments), function(i) {\n  tibble::tibble(\n    treatment = treatments[i],\n    yield = rnorm(n_reps, mean = true_means[i], sd = true_sds[i])\n  )\n}))\n\nyield_summary <- replicate_yields %>%\n  group_by(treatment) %>%\n  summarise(mean_yield = mean(yield), sd_yield = sd(yield)) %>%\n  arrange(desc(mean_yield)) %>%\n  mutate(\n    treatment = factor(treatment, levels = treatment),\n    is_top = mean_yield == max(mean_yield)\n  )\n\n# --- Plot -------------------------------------------------------------------\nplot_title <- \"Crop Yield by Fertilizer Treatment · bar-error · r · ggplot2 · anyplot.ai\"\ntitle_fontsize <- round(12 * 67 / nchar(plot_title))\n\np <- ggplot(yield_summary, aes(x = treatment, y = mean_yield)) +\n  geom_col(aes(alpha = is_top), fill = BRAND, width = 0.6) +\n  geom_errorbar(\n    aes(ymin = mean_yield - sd_yield, ymax = mean_yield + sd_yield),\n    width = 0.2, color = INK, linewidth = 0.6\n  ) +\n  geom_text(\n    aes(y = mean_yield + sd_yield, label = sprintf(\"%.1f\", mean_yield), fontface = ifelse(is_top, \"bold\", \"plain\")),\n    vjust = -0.9, size = 3, color = INK\n  ) +\n  scale_alpha_manual(values = c(`TRUE` = 1, `FALSE` = 0.6), guide = \"none\") +\n  scale_y_continuous(expand = expansion(mult = c(0, 0.14))) +\n  labs(\n    title = plot_title,\n    subtitle = \"Ranked by mean yield (highest first) · error bars show ±1 SD across 8 replicate plots per treatment\",\n    x = \"Fertilizer Treatment\",\n    y = \"Crop Yield (tons/hectare)\"\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.3),\n    axis.title        = element_text(color = INK, size = 10),\n    axis.text         = element_text(color = INK_SOFT, size = 8),\n    axis.ticks        = element_blank(),\n    plot.title        = element_text(color = INK, size = title_fontsize, face = \"bold\"),\n    plot.subtitle     = element_text(color = INK_SOFT, size = 9)\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"}