{"spec_id":"scatter-categorical","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' scatter-categorical: Categorical Scatter Plot\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 82/100 | Created: 2026-09-05\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(ragg)\nlibrary(palmerpenguins)\n\nset.seed(42)\n\n# --- Theme tokens -----------------------------------------------------------\nTHEME       <- Sys.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG     <- if (THEME == \"light\") \"#FAF8F1\" else \"#1A1A17\"\nELEVATED_BG <- if (THEME == \"light\") \"#FFFDF6\" else \"#242420\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\n\n# Imprint palette — first 3 categorical series (see prompts/default-style-guide.md)\nIMPRINT_PALETTE <- c(\"#009E73\", \"#C475FD\", \"#4467A3\")\n\n# --- Data ---------------------------------------------------------------\ndf <- penguins %>%\n  filter(!is.na(bill_length_mm), !is.na(flipper_length_mm)) %>%\n  mutate(species = as.character(species))\n\n# --- Plot -----------------------------------------------------------------\ntitle_text <- \"scatter-categorical · r · ggplot2 · anyplot.ai\"\n\n# Grid lines blended toward the background instead of full-strength INK\n# (ggplot2 does not expose grid alpha directly, so pre-mix the color).\nGRID_COLOR <- grDevices::adjustcolor(INK, alpha.f = 0.2)\n\np <- ggplot(df, aes(x = bill_length_mm, y = flipper_length_mm, color = species, fill = species)) +\n  stat_ellipse(linewidth = 0.6, alpha = 0.6, level = 0.68, show.legend = FALSE) +\n  geom_point(shape = 21, color = \"white\", stroke = 0.3, size = 2.5, alpha = 0.85) +\n  scale_color_manual(values = IMPRINT_PALETTE, guide = \"none\") +\n  scale_fill_manual(values = IMPRINT_PALETTE, name = \"Species\") +\n  labs(\n    title = title_text,\n    x = \"Bill Length (mm)\",\n    y = \"Flipper Length (mm)\"\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  = element_line(color = GRID_COLOR, linewidth = 0.3),\n    panel.grid.minor  = element_blank(),\n    axis.title        = element_text(color = INK, size = 10),\n    axis.text         = element_text(color = INK_SOFT, size = 8),\n    axis.ticks        = element_blank(),\n    plot.title        = element_text(color = INK, size = 12, face = \"plain\"),\n    legend.background = element_rect(fill = ELEVATED_BG, color = NA),\n    legend.key        = element_rect(fill = ELEVATED_BG, color = NA),\n    legend.text       = element_text(color = INK_SOFT, size = 8),\n    legend.title      = element_text(color = INK, size = 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"}