{"spec_id":"map-tilegrid","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' map-tilegrid: Tile Grid Map for Equal-Area Geographic Comparison\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 92/100 | Created: 2026-09-05\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(ragg)\n\nset.seed(42)\n\n# --- Theme tokens (see prompts/default-style-guide.md \"Theme-adaptive Chrome\") ----\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# --- Data: US state tile grid + simulated per-capita income -----------------\n# Row/col approximate each state's real-world position (0-indexed, top-left\n# origin) so the tile layout still reads as a recognizable US map.\nstate_grid <- tibble::tribble(\n  ~region, ~row, ~col,\n  \"AK\", 0, 0,   \"ME\", 0, 10,\n  \"WA\", 1, 0,   \"MT\", 1, 2,   \"ND\", 1, 3,   \"MN\", 1, 4,   \"WI\", 1, 5,\n  \"MI\", 1, 7,   \"NY\", 1, 8,   \"VT\", 1, 9,   \"NH\", 1, 10,\n  \"OR\", 2, 0,   \"ID\", 2, 1,   \"WY\", 2, 2,   \"SD\", 2, 3,   \"IA\", 2, 4,\n  \"IL\", 2, 5,   \"IN\", 2, 6,   \"OH\", 2, 7,   \"PA\", 2, 8,   \"NJ\", 2, 9,\n  \"MA\", 2, 10,\n  \"CA\", 3, 0,   \"NV\", 3, 1,   \"UT\", 3, 2,   \"CO\", 3, 3,   \"NE\", 3, 4,\n  \"MO\", 3, 5,   \"KY\", 3, 6,   \"WV\", 3, 7,   \"VA\", 3, 8,   \"MD\", 3, 9,\n  \"CT\", 3, 10,\n  \"AZ\", 4, 1,   \"NM\", 4, 2,   \"KS\", 4, 3,   \"AR\", 4, 5,   \"TN\", 4, 6,\n  \"NC\", 4, 8,   \"DE\", 4, 9,   \"RI\", 4, 10,\n  \"TX\", 5, 2,   \"OK\", 5, 3,   \"LA\", 5, 4,   \"MS\", 5, 5,   \"AL\", 5, 6,\n  \"SC\", 5, 8,   \"DC\", 5, 9,\n  \"HI\", 6, 0,   \"GA\", 6, 7,\n  \"FL\", 7, 7\n)\n\ndf <- state_grid %>%\n  mutate(income_k = round(pmax(35, rnorm(n(), mean = 58, sd = 11)), 1))\n\n# --- Outlier callouts (data-storytelling touch: national average + hi/lo) --\navg_income <- round(mean(df$income_k), 1)\ntop_state    <- dplyr::slice_max(df, income_k, n = 1, with_ties = FALSE)\nbottom_state <- dplyr::slice_min(df, income_k, n = 1, with_ties = FALSE)\n\ndf <- df %>%\n  mutate(\n    is_outlier  = region %in% c(top_state$region, bottom_state$region),\n    tile_color  = if_else(is_outlier, INK, PAGE_BG),   # neutral anchor for callout ring\n    tile_stroke = if_else(is_outlier, 2.6, 1.2)\n  )\n\n# --- Title (fontsize scales with title length, see plot-generator.md) -------\ntitle_text <- \"US Per-Capita Income by State · map-tilegrid · r · ggplot2 · anyplot.ai\"\ntitle_n <- nchar(title_text, type = \"chars\")\ntitle_size <- max(8, round(12 * min(1, 67 / title_n)))\n\nsubtitle_text <- sprintf(\n  \"National average $%.0fk  ·  Highest: %s ($%.0fk)  ·  Lowest: %s ($%.0fk)\",\n  avg_income, top_state$region, top_state$income_k,\n  bottom_state$region, bottom_state$income_k\n)\n\n# --- Plot ---------------------------------------------------------------------\np <- ggplot(df, aes(x = col, y = -row)) +\n  geom_tile(aes(fill = income_k, color = tile_color, linewidth = tile_stroke),\n            width = 0.88, height = 0.88) +\n  geom_text(aes(label = region), color = \"#FFFFFF\", size = 3.4,\n            fontface = \"bold\") +\n  scale_fill_gradient(low = \"#009E73\", high = \"#4467A3\",\n                       name = \"Per-capita\\nincome ($k)\",\n                       guide = guide_colorbar(title.position = \"top\",\n                                              barwidth  = grid::unit(0.35, \"cm\"),\n                                              barheight = grid::unit(3.2, \"cm\"),\n                                              frame.colour  = INK_SOFT,\n                                              frame.linewidth = 0.3,\n                                              ticks.colour  = INK_SOFT)) +\n  scale_color_identity() +\n  scale_linewidth_identity() +\n  coord_fixed(ratio = 1, clip = \"off\") +\n  labs(title = title_text, subtitle = subtitle_text) +\n  theme_void(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    plot.title          = element_text(color = INK, size = title_size,\n                                        hjust = 0.5,\n                                        margin = margin(b = 6)),\n    plot.subtitle       = element_text(color = INK_SOFT, size = 9,\n                                        hjust = 0.5,\n                                        margin = margin(b = 16)),\n    legend.position     = \"right\",\n    legend.background   = element_rect(fill = ELEVATED_BG, color = NA),\n    legend.title        = element_text(color = INK, size = 10),\n    legend.text         = element_text(color = INK_SOFT, size = 8),\n    legend.key.height   = grid::unit(1.1, \"cm\"),\n    plot.margin         = margin(t = 20, r = 30, b = 20, l = 30)\n  )\n\n# --- Save (both themes, ragg device, see prompts/library/ggplot2.md) --------\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"}