{"spec_id":"histogram-density","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' histogram-density: Density Histogram\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 90/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\"\n\n# Imprint categorical palette (see prompts/default-style-guide.md)\nIMPRINT_PALETTE <- c(\n  \"#009E73\", # 1 — brand green, ALWAYS first series\n  \"#C475FD\", # 2 — lavender\n  \"#4467A3\"  # 3 — blue, used here for the fitted normal curve\n)\n\n# --- Data ---------------------------------------------------------------\n# Simulated adult male height sample (cm) — a classic near-normal continuous\n# measurement, well suited to demonstrating a density histogram against a\n# fitted theoretical PDF.\nheights <- tibble::tibble(height_cm = rnorm(800, mean = 175, sd = 7))\n\nfit_mean <- mean(heights$height_cm)\nfit_sd   <- sd(heights$height_cm)\npdf_curve <- tibble::tibble(\n  x = seq(min(heights$height_cm), max(heights$height_cm), length.out = 200),\n  y = dnorm(x, mean = fit_mean, sd = fit_sd)\n)\n\n# --- Plot -----------------------------------------------------------------\np <- ggplot(heights, aes(x = height_cm)) +\n  geom_histogram(\n    aes(y = after_stat(density)),\n    bins = 30,\n    fill = IMPRINT_PALETTE[1],\n    color = PAGE_BG,\n    linewidth = 0.3,\n    alpha = 0.9\n  ) +\n  geom_line(\n    data = pdf_curve,\n    aes(x = x, y = y, color = \"Normal density\"),\n    linewidth = 1.2\n  ) +\n  scale_color_manual(values = IMPRINT_PALETTE[3], name = NULL) +\n  labs(\n    title = \"histogram-density · r · ggplot2 · anyplot.ai\",\n    x = \"Height (cm)\",\n    y = \"Density\"\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.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.position          = \"inside\",\n    legend.position.inside   = c(0.86, 0.88),\n    legend.background = element_blank(),\n    legend.text       = element_text(color = INK_SOFT, size = 8),\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"}