{"spec_id":"scatter-annotated","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' scatter-annotated: Annotated Scatter Plot with Text Labels\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 91/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\"\nINK_MUTED <- if (THEME == \"light\") \"#6B6A63\" else \"#A8A79F\"\nGRID      <- if (THEME == \"light\") \"#D8D7D0\" else \"#3A3A36\"  # ~15% INK over PAGE_BG\nBRAND     <- \"#009E73\"  # Imprint palette position 1 — always first series\n\n# --- Data ---------------------------------------------------------------------\n# Background cloud: R&D spending vs. revenue for unnamed tech companies\nn_background <- 24\nrd_spend_bg  <- runif(n_background, 8, 110)\nrevenue_bg   <- 2.8 * rd_spend_bg + 45 + rnorm(n_background, 0, 55)\n\nbackground <- tibble(\n  rd_spend = rd_spend_bg,\n  revenue  = revenue_bg,\n  label    = NA_character_,\n  nudge_x  = 0,\n  nudge_y  = 0\n)\n\n# Named companies worth calling out: leaders, an efficient outlier, laggards\ncompanies <- tibble(\n  rd_spend = c(95, 88, 15, 22, 60, 45, 105, 30),\n  revenue  = c(340, 310, 120, 35, 240, 220, 200, 95),\n  label    = c(\n    \"Nimbus Systems\", \"Solace AI\", \"Cascade Software\", \"Fenwick Labs\",\n    \"Vertex Robotics\", \"Quanta Devices\", \"Orbital Dynamics\", \"BrightWave Energy\"\n  ),\n  nudge_x  = c(-8, 6, 10, 6, 8, -8, -10, 6),\n  nudge_y  = c(18, -18, 14, 14, -16, 16, 12, -14)\n)\n\npoints <- bind_rows(background, companies) %>%\n  mutate(is_named = !is.na(label))\n\n# --- Plot -----------------------------------------------------------------\ntitle_text <- \"R&D Spending vs. Revenue · scatter-annotated · r · ggplot2 · anyplot.ai\"\n\np <- ggplot(points, aes(x = rd_spend, y = revenue)) +\n  geom_segment(\n    data = companies,\n    aes(x = rd_spend, y = revenue,\n        xend = rd_spend + nudge_x * 0.7, yend = revenue + nudge_y * 0.7),\n    color = INK_MUTED, linewidth = 0.3\n  ) +\n  geom_point(aes(size = is_named), color = BRAND, alpha = 0.7) +\n  geom_text(\n    data = companies,\n    aes(x = rd_spend + nudge_x, y = revenue + nudge_y, label = label,\n        hjust = ifelse(nudge_x > 0, 0, 1)),\n    color = INK, size = 3.2, fontface = \"plain\"\n  ) +\n  scale_size_manual(values = c(`FALSE` = 2.5, `TRUE` = 3.5), guide = \"none\") +\n  labs(x = \"R&D Spending ($M)\", y = \"Annual Revenue ($M)\", title = title_text) +\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, linewidth = 0.4),\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 = 11),\n    plot.margin       = margin(12, 16, 12, 12)\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"}