{"spec_id":"bubble-map-geographic","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' bubble-map-geographic: Bubble Map with Sized Geographic Markers\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 86/100 | Created: 2026-05-18\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(scales)\nlibrary(ragg)\nlibrary(tibble)\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\"\nOCEAN_BG    <- if (THEME == \"light\") \"#D6E8F2\" else \"#182530\"\nGRID_COLOR  <- if (THEME == \"light\") \"#AACCDC\" else \"#2C4455\"\nIMPRINT   <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\")\n\n# Data: Major world cities with population (millions, 2023 estimates)\ncities <- tibble(\n  city       = c(\n    \"Tokyo\", \"Delhi\", \"Shanghai\", \"São Paulo\", \"Mexico City\",\n    \"Cairo\", \"Mumbai\", \"Beijing\", \"New York\", \"Dhaka\",\n    \"Karachi\", \"Buenos Aires\", \"Kolkata\", \"Lagos\", \"Istanbul\",\n    \"Kinshasa\", \"Manila\", \"Rio de Janeiro\", \"Tianjin\", \"Guangzhou\",\n    \"Los Angeles\", \"Moscow\", \"Shenzhen\", \"Bangalore\", \"Paris\",\n    \"Jakarta\", \"Chennai\", \"Lima\", \"Chicago\", \"Lahore\",\n    \"London\", \"Tehran\", \"Seoul\", \"Bangkok\", \"Nairobi\",\n    \"Sydney\", \"Singapore\", \"Ho Chi Minh City\", \"Bogotá\", \"Johannesburg\"\n  ),\n  lat        = c(\n     35.7,  28.6,  31.2, -23.5,  19.4,\n     30.1,  19.1,  39.9,  40.7,  23.8,\n     24.9, -34.6,  22.6,   6.5,  41.0,\n     -4.3,  14.6, -22.9,  39.1,  23.1,\n     34.1,  55.8,  22.5,  12.9,  48.9,\n     -6.2,  13.1, -12.1,  41.9,  31.6,\n     51.5,  35.7,  37.6,  13.8,  -1.3,\n    -33.9,   1.3,  10.8,   4.7, -26.2\n  ),\n  lon        = c(\n    139.7,  77.2, 121.5, -46.6, -99.1,\n     31.2,  72.9, 116.4, -74.0,  90.4,\n     67.0, -58.4,  88.4,   3.4,  29.0,\n     15.3, 121.0, -43.2, 117.2, 113.3,\n   -118.2,  37.6, 114.1,  77.6,   2.3,\n    106.8,  80.3, -77.0, -87.6,  74.3,\n     -0.1,  51.4, 126.9, 100.5,  36.8,\n    151.2, 103.8, 106.7, -74.1,  28.0\n  ),\n  population = c(\n    37.4, 32.9, 28.5, 22.4, 22.1,\n    21.8, 21.7, 21.5, 18.8, 22.5,\n    17.2, 15.5, 14.9, 14.9, 15.4,\n    17.1, 14.4, 13.7, 15.7, 16.1,\n    12.5, 12.4, 13.4, 12.8, 11.1,\n    11.2, 10.5, 11.0,  8.9, 14.0,\n     9.5,  9.6,  9.9, 11.1,  5.3,\n     5.4,  6.0,  9.3, 11.3,  6.1\n  ),\n  continent  = c(\n    \"Asia\", \"Asia\", \"Asia\", \"S. America\", \"N. America\",\n    \"Africa\", \"Asia\", \"Asia\", \"N. America\", \"Asia\",\n    \"Asia\", \"S. America\", \"Asia\", \"Africa\", \"Europe\",\n    \"Africa\", \"Asia\", \"S. America\", \"Asia\", \"Asia\",\n    \"N. America\", \"Europe\", \"Asia\", \"Asia\", \"Europe\",\n    \"Asia\", \"Asia\", \"S. America\", \"N. America\", \"Asia\",\n    \"Europe\", \"Asia\", \"Asia\", \"Asia\", \"Africa\",\n    \"Oceania\", \"Asia\", \"Asia\", \"S. America\", \"Africa\"\n  )\n)\n\n# Continent reference labels for geographic context\nregion_labels <- tibble(\n  label = c(\"NORTH\\nAMERICA\", \"SOUTH\\nAMERICA\", \"EUROPE\", \"AFRICA\", \"ASIA\", \"AUSTRALIA\"),\n  lon   = c(-100, -60, 10, 20, 95, 134),\n  lat   = c(50, -20, 55, 4, 48, -27)\n)\n\n# Color mapping by continent (Okabe-Ito order, Asia first = #009E73)\ncontinent_colors <- c(\n  \"Asia\"       = IMPRINT[1],\n  \"Africa\"     = IMPRINT[2],\n  \"N. America\" = IMPRINT[3],\n  \"S. America\" = IMPRINT[4],\n  \"Europe\"     = IMPRINT[5],\n  \"Oceania\"    = IMPRINT[6]\n)\n\nLABEL_COLOR <- if (THEME == \"light\") \"#7A8C96\" else \"#4A6070\"\n\n# Plot\np <- ggplot(cities, aes(x = lon, y = lat)) +\n  geom_text(\n    data  = region_labels,\n    aes(x = lon, y = lat, label = label),\n    color = LABEL_COLOR,\n    size  = 4,\n    fontface = \"bold\",\n    lineheight = 0.85,\n    inherit.aes = FALSE\n  ) +\n  geom_point(\n    aes(size = population, color = continent),\n    alpha = 0.70,\n    shape = 16\n  ) +\n  scale_color_manual(\n    values = continent_colors,\n    name   = \"Continent\"\n  ) +\n  scale_size_area(\n    max_size = 24,\n    name     = \"Population\",\n    breaks   = c(5, 10, 20, 37),\n    labels   = c(\"5M\", \"10M\", \"20M\", \"37M\")\n  ) +\n  scale_x_continuous(\n    breaks = seq(-150, 150, by = 30),\n    labels = function(x) paste0(abs(x), ifelse(x < 0, \"°W\", ifelse(x > 0, \"°E\", \"°\")))\n  ) +\n  scale_y_continuous(\n    breaks = seq(-60, 80, by = 30),\n    labels = function(y) paste0(abs(y), ifelse(y < 0, \"°S\", ifelse(y > 0, \"°N\", \"°\")))\n  ) +\n  coord_fixed(ratio = 1.3, xlim = c(-175, 175), ylim = c(-62, 82)) +\n  labs(\n    title    = \"World’s Largest Cities · bubble-map-geographic · r · ggplot2 · anyplot.ai\",\n    subtitle = \"Bubble size proportional to city population (millions), 2023 estimates\",\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 = OCEAN_BG,    color = NA),\n    panel.grid.major  = element_line(color = GRID_COLOR, linewidth = 0.4),\n    panel.grid.minor  = element_blank(),\n    panel.border      = element_rect(color = INK_SOFT,   fill = NA, linewidth = 0.6),\n    axis.title        = element_text(color = INK,        size = 20),\n    axis.text         = element_text(color = INK_SOFT,   size = 14),\n    plot.title        = element_text(color = INK,        size = 22, face = \"bold\"),\n    plot.subtitle     = element_text(color = INK_SOFT,   size = 16),\n    legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT, linewidth = 0.4),\n    legend.text       = element_text(color = INK_SOFT,   size = 14),\n    legend.title      = element_text(color = INK,        size = 16),\n    legend.key        = element_rect(fill = NA,          color = NA),\n    plot.margin       = margin(20, 30, 20, 20)\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"}