{"spec_id":"ridgeline-basic","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' ridgeline-basic: Basic Ridgeline Plot\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 91/100 | Created: 2026-07-25\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(tidyr)\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# --- Data: monthly high-temperature readings, seasonal pattern --------------\nmonths        <- month.abb\nseasonal_mean <- c(2, 4, 8, 13, 18, 23, 26, 25, 20, 14, 8, 3)\nseasonal_sd   <- c(3.2, 3.0, 3.4, 3.6, 3.2, 2.8, 2.6, 2.6, 3.0, 3.2, 3.4, 3.2)\n\ntemperatures <- do.call(rbind, lapply(seq_along(months), function(i) {\n  data.frame(\n    month       = months[i],\n    temperature = rnorm(180, mean = seasonal_mean[i], sd = seasonal_sd[i])\n  )\n}))\ntemperatures$month <- factor(temperatures$month, levels = months)\n\n# --- Per-group density curves, computed natively (ggridges is unavailable) --\nridge_curves <- temperatures %>%\n  group_by(month) %>%\n  reframe(\n    x = density(temperature, n = 256, adjust = 1.2)$x,\n    y = density(temperature, n = 256, adjust = 1.2)$y\n  ) %>%\n  mutate(idx = as.integer(month))\n\nspacing <- 1\nscale_h <- spacing / max(ridge_curves$y) * 1.65\n\nridge_curves <- ridge_curves %>%\n  mutate(\n    baseline = idx * spacing,\n    ymax     = baseline + y * scale_h,\n    # Bottom (earliest month) ridges draw last so they sit in front of the\n    # ridges behind them, producing the classic overlapping-mountain look.\n    z        = factor(month, levels = rev(months))\n  )\n\n# --- Plot ---------------------------------------------------------------------\nplot_title     <- \"Monthly Temperatures · ridgeline-basic · r · ggplot2 · anyplot.ai\"\ntitle_fontsize <- round(12 * min(1, 67 / nchar(plot_title)))\n\np <- ggplot(ridge_curves) +\n  geom_ribbon(\n    aes(x = x, ymin = baseline, ymax = ymax, group = z, fill = idx),\n    colour = PAGE_BG, linewidth = 0.6\n  ) +\n  scale_fill_gradient(low = \"#009E73\", high = \"#4467A3\", guide = \"none\") +\n  scale_y_continuous(breaks = spacing * seq_along(months), labels = months) +\n  labs(title = plot_title, x = \"Temperature (°C)\", y = NULL) +\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         = element_blank(),\n    axis.line.x        = element_line(color = INK_SOFT, linewidth = 0.4),\n    axis.title.x       = element_text(color = INK, size = 10),\n    axis.title.y       = element_blank(),\n    axis.text.x        = element_text(color = INK_SOFT, size = 8),\n    axis.text.y        = element_text(color = INK_SOFT, size = 8),\n    axis.ticks         = element_blank(),\n    plot.title         = element_text(color = INK, size = title_fontsize),\n    plot.margin        = margin(12, 20, 10, 10)\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"}