{"spec_id":"scatter-embedding","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' scatter-embedding: t-SNE and UMAP Embedding Visualization\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 90/100 | Created: 2026-08-11\n\nlibrary(ggplot2)\nlibrary(tibble)\nlibrary(ragg)\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\"\nIMPRINT_PALETTE <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\")\n\n# --- Data: UMAP projection of PBMC single-cell RNA-seq profiles -------------\n# Cluster geometry (center, spread, rotation) mimics the elongated, irregular\n# blobs a real non-linear embedding produces, rather than circular Gaussians.\ncell_types <- c(\"CD4+ T cells\", \"CD8+ T cells\", \"B cells\", \"NK cells\", \"Monocytes\", \"Dendritic cells\")\ncluster_n  <- c(700, 550, 450, 350, 400, 250)\ncenter_x   <- c(-6.0, -3.5, 5.5, -8.2, 6.5, 1.5)\ncenter_y   <- c(2.0, -3.0, 2.5, -2.6, -2.0, 4.5)\nspread_x   <- c(1.3, 1.0, 1.1, 0.8, 1.2, 0.8)\nspread_y   <- c(0.55, 0.5, 0.6, 0.4, 0.5, 0.4)\nangle_deg  <- c(20, -30, 10, 60, -15, 45)\n\nn_total    <- sum(cluster_n)\ncluster_id <- factor(rep(seq_along(cluster_n), cluster_n), labels = cell_types)\ncx_vec     <- rep(center_x, cluster_n)\ncy_vec     <- rep(center_y, cluster_n)\nsx_vec     <- rep(spread_x, cluster_n)\nsy_vec     <- rep(spread_y, cluster_n)\nangle_vec  <- rep(angle_deg, cluster_n) * pi / 180\n\nraw_x <- rnorm(n_total, mean = 0, sd = sx_vec)\nraw_y <- rnorm(n_total, mean = 0, sd = sy_vec)\n\nembedding <- tibble::tibble(\n  x         = raw_x * cos(angle_vec) - raw_y * sin(angle_vec) + cx_vec,\n  y         = raw_x * sin(angle_vec) + raw_y * cos(angle_vec) + cy_vec,\n  cell_type = cluster_id\n)\n\n# Cluster centroids for the optional label annotations called out in the spec.\ncentroids <- aggregate(cbind(x, y) ~ cell_type, data = embedding, FUN = mean)\n\n# --- Title (scales fontsize to length; mandated title is well under the\n# 67-char baseline here, so this resolves to the library default of 12pt) ---\ntitle_text  <- \"scatter-embedding · r · ggplot2 · anyplot.ai\"\ntitle_ratio <- if (nchar(title_text) > 67) 67 / nchar(title_text) else 1.0\ntitle_size  <- max(8, round(12 * title_ratio))\n\n# --- Plot ---------------------------------------------------------------\np <- ggplot(embedding, aes(x = x, y = y, color = cell_type, shape = cell_type)) +\n  geom_point(size = 1.8, alpha = 0.5, stroke = 0.4) +\n  geom_label(\n    data          = centroids,\n    aes(x = x, y = y, label = cell_type),\n    inherit.aes   = FALSE,\n    color         = INK,\n    fill          = ELEVATED_BG,\n    alpha         = 0.85,\n    size          = 2.5,\n    label.size    = 0,\n    label.padding = unit(0.12, \"lines\"),\n    fontface      = \"bold\"\n  ) +\n  scale_color_manual(values = IMPRINT_PALETTE, name = \"Cell type\") +\n  scale_shape_manual(values = c(16, 17, 15, 18, 3, 8), name = \"Cell type\") +\n  labs(\n    title    = title_text,\n    subtitle = \"UMAP projection (n_neighbors = 15) of PBMC single-cell RNA-seq profiles\",\n    x        = \"UMAP 1\",\n    y        = \"UMAP 2\"\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        = element_blank(),\n    axis.text         = element_blank(),\n    axis.ticks        = element_blank(),\n    axis.line         = element_line(color = INK_SOFT, linewidth = 0.4),\n    axis.title        = element_text(color = INK, size = 10),\n    plot.title        = element_text(color = INK, size = title_size, face = \"bold\"),\n    plot.subtitle     = element_text(color = INK_SOFT, size = 9),\n    plot.margin       = margin(t = 10, r = 14, b = 10, l = 10),\n    legend.position   = \"right\",\n    legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT, linewidth = 0.3),\n    legend.margin     = margin(t = 6, r = 8, b = 6, l = 8),\n    legend.key        = element_rect(fill = ELEVATED_BG, color = NA),\n    legend.key.size   = unit(0.9, \"lines\"),\n    legend.text       = element_text(color = INK_SOFT, size = 8),\n    legend.title      = element_text(color = INK, size = 9, face = \"bold\")\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"}