{"spec_id":"histogram-stepwise","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' histogram-stepwise: Step Histogram\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 85/100 | Created: 2026-09-05\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\"\nIMPRINT_PALETTE <- c(\"#009E73\", \"#C475FD\")\n\n# --- Data ---------------------------------------------------------------\n# Reaction times (ms) for two lighting conditions in a visual response task.\nn_subjects <- 1200\nbright_light  <- rnorm(n_subjects, mean = 320, sd = 45)\ndim_light     <- rnorm(n_subjects, mean = 370, sd = 55)\n\nbin_width <- 12\nbreaks <- seq(\n  floor(min(bright_light, dim_light) / bin_width) * bin_width,\n  ceiling(max(bright_light, dim_light) / bin_width) * bin_width,\n  by = bin_width\n)\n\nbright_counts <- hist(bright_light, breaks = breaks, plot = FALSE)$counts\ndim_counts    <- hist(dim_light, breaks = breaks, plot = FALSE)$counts\n\nsteps_df <- bind_rows(\n  tibble::tibble(\n    bin_start = breaks[-length(breaks)],\n    count     = bright_counts,\n    condition = \"Bright light\"\n  ),\n  tibble::tibble(\n    bin_start = breaks[-length(breaks)],\n    count     = dim_counts,\n    condition = \"Dim light\"\n  )\n) |>\n  mutate(condition = factor(condition, levels = c(\"Bright light\", \"Dim light\")))\n\nmean_bright <- mean(bright_light)\nmean_dim    <- mean(dim_light)\ngap_label   <- sprintf(\"+%.0f ms slower under dim light\", mean_dim - mean_bright)\n\n# --- Plot ---------------------------------------------------------------\np <- ggplot(steps_df, aes(x = bin_start, y = count, color = condition)) +\n  geom_vline(xintercept = mean_bright, color = IMPRINT_PALETTE[1], linetype = \"dashed\", linewidth = 0.5, alpha = 0.6) +\n  geom_vline(xintercept = mean_dim, color = IMPRINT_PALETTE[2], linetype = \"dashed\", linewidth = 0.5, alpha = 0.6) +\n  geom_step(linewidth = 1.1, direction = \"hv\") +\n  annotate(\n    \"text\",\n    x     = (mean_bright + mean_dim) / 2,\n    y     = max(steps_df$count) * 1.12,\n    label = gap_label,\n    color = INK_SOFT,\n    size  = 3,\n    hjust = 0.5\n  ) +\n  scale_color_manual(values = IMPRINT_PALETTE) +\n  scale_y_continuous(expand = expansion(mult = c(0, 0.18))) +\n  labs(\n    title  = \"histogram-stepwise · r · ggplot2 · anyplot.ai\",\n    x      = \"Reaction Time (ms)\",\n    y      = \"Number of Trials\",\n    color  = \"Condition\"\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.line         = element_line(color = INK_SOFT),\n    plot.title        = element_text(color = INK, size = 12),\n    legend.position   = \"top\",\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"}