{"spec_id":"voronoi-basic","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' voronoi-basic: Voronoi Diagram for Spatial Partitioning\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 90/100 | Created: 2026-05-17\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\"\nELEVATED_BG <- if (THEME == \"light\") \"#FFFDF6\" else \"#242420\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\nIMPRINT   <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\",\n                 \"#AE3030\", \"#2ABCCD\", \"#954477\")\n\n# --- Data: Seed points for Voronoi diagram --------------------------------\nn_points <- 25\nseed_points <- data.frame(\n  id = 1:n_points,\n  x = runif(n_points, 0, 100),\n  y = runif(n_points, 0, 100)\n)\n\n# --- Compute Voronoi cells using distance-based approach ------------------\n# Create a fine grid and assign each grid point to its nearest seed\ngrid_resolution <- 200\ngrid_df <- expand.grid(\n  x = seq(0, 100, length.out = grid_resolution),\n  y = seq(0, 100, length.out = grid_resolution)\n)\n\n# Calculate distances from each grid point to all seeds\ndistances <- matrix(NA, nrow = nrow(grid_df), ncol = n_points)\nfor (i in seq_len(n_points)) {\n  distances[, i] <- sqrt(\n    (grid_df$x - seed_points$x[i])^2 +\n    (grid_df$y - seed_points$y[i])^2\n  )\n}\n\n# Assign each grid point to the nearest seed\ngrid_df$region <- apply(distances, 1, which.min)\ngrid_df$cell_id <- seed_points$id[grid_df$region]\n\n# Join with seed point colors\ngrid_df <- grid_df %>%\n  mutate(\n    color_idx = ((cell_id - 1) %% 7) + 1,\n    color = IMPRINT[color_idx]\n  )\n\n# --- Plot -------------------------------------------------------------------\np <- ggplot(grid_df, aes(x = x, y = y, fill = color)) +\n  geom_raster() +\n  geom_point(\n    data = seed_points,\n    aes(x = x, y = y),\n    inherit.aes = FALSE,\n    color = INK,\n    size = 5,\n    shape = 21,\n    fill = \"white\",\n    stroke = 1.5\n  ) +\n  scale_fill_identity() +\n  scale_x_continuous(limits = c(0, 100), expand = c(0, 0)) +\n  scale_y_continuous(limits = c(0, 100), expand = c(0, 0)) +\n  coord_fixed() +\n  labs(\n    title = \"voronoi-basic · ggplot2 · anyplot.ai\",\n    x = \"X\",\n    y = \"Y\"\n  ) +\n  theme_minimal(base_size = 14) +\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_blank(),\n    panel.grid.minor  = element_blank(),\n    panel.border      = element_rect(color = INK_SOFT, fill = NA, linewidth = 0.8),\n    axis.title        = element_text(color = INK, size = 20),\n    axis.text         = element_text(color = INK_SOFT, size = 16),\n    plot.title        = element_text(color = INK, size = 24, face = \"bold\"),\n    legend.position   = \"none\"\n  )\n\n# --- Save -------------------------------------------------------------------\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 16,\n  height   = 9,\n  units    = \"in\",\n  dpi      = 300\n)\n"}