{"spec_id":"heatmap-geographic","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' heatmap-geographic: Geographic Heatmap for Spatial Density\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 87/100 | Updated: 2026-05-19\n\nlibrary(ggplot2)\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\"\n\n# Data: simulated convective storm event locations over the eastern United States\ngulf_coast <- data.frame(\n  longitude = rnorm(420, mean = -90, sd = 3.0),\n  latitude  = rnorm(420, mean = 30,  sd = 1.8)\n)\ngreat_plains <- data.frame(\n  longitude = rnorm(500, mean = -96, sd = 4.5),\n  latitude  = rnorm(500, mean = 37,  sd = 3.0)\n)\nappalachians <- data.frame(\n  longitude = rnorm(330, mean = -79, sd = 2.5),\n  latitude  = rnorm(330, mean = 40,  sd = 2.2)\n)\nflorida_pen <- data.frame(\n  longitude = rnorm(250, mean = -82, sd = 1.5),\n  latitude  = rnorm(250, mean = 27,  sd = 1.5)\n)\n\nevents <- rbind(gulf_coast, great_plains, appalachians, florida_pen)\n\n# Kernel density estimation over eastern US\nlon_range <- c(-105, -65)\nlat_range <- c(24,   51)\n\nkde_out <- MASS::kde2d(\n  x    = events$longitude,\n  y    = events$latitude,\n  n    = 200,\n  h    = c(2.5, 2.0),\n  lims = c(lon_range, lat_range)\n)\n\nkde_df          <- expand.grid(longitude = kde_out$x, latitude = kde_out$y)\nkde_df$density  <- as.vector(kde_out$z)\nkde_df$density[kde_df$density < quantile(kde_df$density, 0.15)] <- NA\n\n# Plot\np <- ggplot() +\n  geom_raster(\n    data        = kde_df,\n    aes(x = longitude, y = latitude, fill = density),\n    interpolate = TRUE\n  ) +\n  scale_fill_viridis_c(\n    option   = \"inferno\",\n    name     = \"Storm\\nDensity\",\n    na.value = \"transparent\",\n    guide    = guide_colorbar(\n      barwidth       = 1.5,\n      barheight      = 8,\n      title.position = \"top\",\n      title.hjust    = 0.5\n    )\n  ) +\n  coord_cartesian(xlim = lon_range, ylim = lat_range, expand = FALSE) +\n  labs(\n    title = \"Convective Storm Event Density · heatmap-geographic · r · ggplot2 · anyplot.ai\",\n    x     = \"Longitude\",\n    y     = \"Latitude\"\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_line(color = INK_SOFT, linewidth = 0.25, linetype = \"dotted\"),\n    panel.grid.minor  = element_blank(),\n    panel.border      = element_blank(),\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 = 22, margin = margin(b = 12)),\n    legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT, linewidth = 0.4),\n    legend.text       = element_text(color = INK_SOFT, size = 16),\n    legend.title      = element_text(color = INK,      size = 18),\n    legend.position   = \"right\",\n    plot.margin       = margin(15, 15, 15, 15)\n  )\n\n# Add geographic borders when the maps package is available\nif (requireNamespace(\"maps\", quietly = TRUE)) {\n  countries <- map_data(\"world\", region = c(\"USA\", \"Canada\", \"Mexico\"))\n  us_states <- map_data(\"state\")\n\n  p <- p +\n    geom_polygon(\n      data    = countries,\n      mapping = aes(x = long, y = lat, group = group),\n      fill    = NA, color = INK_SOFT, linewidth = 0.5,\n      inherit.aes = FALSE\n    ) +\n    geom_polygon(\n      data    = us_states,\n      mapping = aes(x = long, y = lat, group = group),\n      fill    = NA, color = INK_SOFT, linewidth = 0.2,\n      inherit.aes = FALSE\n    )\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"}