{"spec_id":"sparkline-basic","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' sparkline-basic: Basic Sparkline\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 87/100 | Created: 2026-09-09\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\"\n\n# Imprint palette (see prompts/default-style-guide.md \"Categorical Palette\")\nBRAND <- \"#009E73\" # position 1 — the trend line, ALWAYS first series\nLOW_MARK <- \"#AE3030\" # position 5 — series minimum\nHIGH_MARK <- \"#4467A3\" # position 3 — series maximum\n\n# --- Data ---------------------------------------------------------------------\n# Single stock's closing price over one trading quarter — the sparkline\n# convention of embedding a trend inline (financial table cell) without any\n# axes, ticks, or gridlines.\nn_points <- 90\nday <- 1:n_points\nclosing_price <- 142 + 14 * sin(2 * pi * day / 45 - 1) + cumsum(rnorm(n_points, mean = 0.12, sd = 1.3))\n\ntrend <- data.frame(day = day, closing_price = closing_price)\ni_min <- which.min(closing_price)\ni_max <- which.max(closing_price)\ni_first <- 1\ni_last <- n_points\n\n# --- Plot -----------------------------------------------------------------\n# geom_ribbon fills the area under the line for the classic sparkline look;\n# geom_point marks the series extremes, the starting point, and the latest\n# value — the only highlights the spec allows before it stops being \"basic\".\n# Narrow side margins let the mark span nearly the full canvas width, and\n# aspect.ratio ~0.18 keeps the panel a compact 5-6:1 band while still filling\n# a healthy share of the fixed 3200x1800 canvas height.\np <- ggplot(trend, aes(x = day, y = closing_price)) +\n  geom_ribbon(aes(ymin = min(closing_price), ymax = closing_price), fill = BRAND, alpha = 0.12) +\n  geom_line(color = BRAND, linewidth = 1.9, lineend = \"round\") +\n  geom_point(data = trend[i_first, ], shape = 21, color = INK, fill = PAGE_BG, size = 3.2, stroke = 1.2) +\n  geom_point(data = trend[i_min, ], color = LOW_MARK, size = 3.8) +\n  geom_point(data = trend[i_max, ], color = HIGH_MARK, size = 3.8) +\n  geom_point(data = trend[i_last, ], color = BRAND, size = 4.2) +\n  scale_x_continuous(expand = expansion(mult = c(0.02, 0.02))) +\n  scale_y_continuous(expand = expansion(mult = c(0.12, 0.12))) +\n  labs(title = \"sparkline-basic · r · ggplot2 · anyplot.ai\") +\n  theme_void(base_size = 8) +\n  theme(\n    aspect.ratio = 0.18, # compact ~5.5:1 band — the sparkline's defining shape\n    plot.background = element_rect(fill = PAGE_BG, color = PAGE_BG),\n    panel.background = element_rect(fill = PAGE_BG, color = NA),\n    plot.title = element_text(color = INK, size = 15, hjust = 0.5, margin = margin(b = 24)),\n    plot.margin = margin(t = 30, r = 40, b = 30, l = 40)\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"}