{"spec_id":"histogram-overlapping","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' histogram-overlapping: Overlapping Histograms\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 89/100 | Created: 2026-08-18\n\nlibrary(ggplot2)\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\"\nIMPRINT_PALETTE <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\",\n                     \"#AE3030\", \"#2ABCCD\", \"#954477\", \"#99B314\")\n\n# --- Data -----------------------------------------------------------------\nn <- 200\ncompletion_time <- c(\n  rnorm(n, mean = 45, sd = 8),\n  rnorm(n, mean = 39, sd = 7),\n  rnorm(n, mean = 51, sd = 9)\n)\ndesign <- factor(\n  rep(c(\"Design A\", \"Design B\", \"Design C\"), each = n),\n  levels = c(\"Design A\", \"Design B\", \"Design C\")\n)\ndf <- tibble::tibble(completion_time = completion_time, design = design)\n\nbinwidth <- diff(range(df$completion_time)) / 28\n\n# Group means drive the dashed reference lines and the fastest-design callout\ngroup_means <- tapply(df$completion_time, df$design, mean)\nmean_df <- tibble::tibble(\n  design    = factor(names(group_means), levels = levels(df$design)),\n  mean_time = as.numeric(group_means)\n)\nfastest <- mean_df[which.min(mean_df$mean_time), ]\n\n# --- Plot -------------------------------------------------------------------\np <- ggplot(df, aes(x = completion_time, fill = design)) +\n  geom_histogram(\n    position  = \"identity\",\n    binwidth  = binwidth,\n    alpha     = 0.5,\n    color     = INK_SOFT,\n    linewidth = 0.15\n  ) +\n  geom_vline(\n    xintercept = fastest$mean_time,\n    color      = IMPRINT_PALETTE[which(levels(df$design) == fastest$design)],\n    linetype   = \"dashed\",\n    linewidth  = 0.6\n  ) +\n  annotate(\n    \"text\",\n    x        = fastest$mean_time,\n    y        = Inf,\n    label    = sprintf(\"%s: fastest avg (%.0fs)\", fastest$design, fastest$mean_time),\n    hjust    = -0.05,\n    vjust    = 1.6,\n    size     = 3,\n    fontface = \"bold\",\n    color    = IMPRINT_PALETTE[which(levels(df$design) == fastest$design)]\n  ) +\n  scale_fill_manual(values = IMPRINT_PALETTE[1:3], name = \"UI design\") +\n  scale_y_continuous(expand = expansion(mult = c(0, 0.08))) +\n  labs(\n    title = \"histogram-overlapping · r · ggplot2 · anyplot.ai\",\n    x     = \"Task Completion Time (seconds)\",\n    y     = \"Number of Users\"\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.15),\n    axis.title        = element_text(color = INK, size = 10),\n    axis.text         = element_text(color = INK_SOFT, size = 8),\n    axis.line         = element_line(color = INK_SOFT),\n    plot.title        = element_text(color = INK, size = 12),\n    legend.position   = \"right\",\n    legend.title      = element_text(color = INK, size = 10),\n    legend.text       = element_text(color = INK_SOFT, size = 8),\n    legend.background = element_blank(),\n    legend.key        = element_blank()\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"}