{"spec_id":"network-transport-static","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' network-transport-static: Static Transport Network Diagram\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 88/100 | Created: 2026-05-18\n\nlibrary(ggplot2)\nlibrary(dplyr)\nlibrary(tidyr)\nlibrary(ragg)\nlibrary(grid)\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\"\nINK_MUTED   <- if (THEME == \"light\") \"#6B6A63\" else \"#A8A79F\"\n\nIMPRINT   <- c(\n  \"#009E73\",  # 1 — regional (first categorical series)\n  \"#C475FD\",  # 2 — express\n  \"#4467A3\"   # 3 — local\n)\n\n# --- Data: Regional rail network with 12 stations and 30 routes ----------------\nstations <- data.frame(\n  id    = 1:12,\n  label = c(\"Central\", \"North Hub\", \"West Gate\", \"East Plaza\", \"South Terminal\",\n            \"Airport\", \"Harbor\", \"Tech Park\", \"Suburb 1\", \"Suburb 2\", \"Suburb 3\", \"Junction\"),\n  x     = c(5, 5, 2, 8, 5, 8, 2, 8, 3, 7, 3, 5),\n  y     = c(6, 9, 6, 6, 3, 9, 3, 3, 8, 8, 1, 5),\n  stringsAsFactors = FALSE\n)\n\nroutes <- data.frame(\n  source_id = c(1, 1, 1, 1, 1, 2, 2, 2, 3, 3, 3, 4, 4, 4, 4, 5, 5, 5, 6, 6, 6, 7, 7, 7, 8, 8, 8, 9, 10, 11),\n  target_id = c(2, 3, 4, 5, 6, 6, 9, 11, 7, 1, 9, 1, 6, 8, 12, 1, 7, 11, 2, 4, 8, 3, 5, 1, 4, 5, 12, 2, 6, 5),\n  route_id = c(\"RE01\", \"RE02\", \"RE03\", \"RE04\", \"RE05\", \"EX01\", \"RE06\", \"RE07\", \"LO01\", \"LO02\", \"RE08\", \"LO03\", \"RE09\", \"EX02\", \"LO04\", \"RE10\", \"RE11\", \"LO05\", \"RE12\", \"EX03\", \"EX04\", \"LO06\", \"LO07\", \"LO08\", \"RE13\", \"RE14\", \"EX05\", \"RE15\", \"RE16\", \"RE17\"),\n  departure_time = c(\"08:15\", \"08:30\", \"08:45\", \"09:00\", \"09:30\", \"07:45\", \"09:15\", \"10:00\", \"08:00\", \"09:45\", \"10:15\", \"10:30\", \"11:00\", \"11:15\", \"11:30\", \"12:00\", \"12:30\", \"13:00\", \"06:45\", \"07:15\", \"08:15\", \"13:30\", \"14:00\", \"14:30\", \"15:00\", \"15:30\", \"16:00\", \"16:30\", \"17:00\", \"17:30\"),\n  arrival_time = c(\"08:45\", \"09:00\", \"09:30\", \"09:45\", \"10:15\", \"08:30\", \"10:00\", \"10:45\", \"08:35\", \"10:30\", \"11:00\", \"11:00\", \"11:45\", \"12:00\", \"12:15\", \"12:45\", \"13:15\", \"13:45\", \"07:30\", \"08:00\", \"09:00\", \"14:15\", \"14:45\", \"15:15\", \"15:45\", \"16:15\", \"16:45\", \"17:15\", \"17:45\", \"18:15\"),\n  route_type = c(\"Regional\", \"Regional\", \"Regional\", \"Regional\", \"Regional\", \"Express\", \"Regional\", \"Regional\", \"Local\", \"Local\", \"Regional\", \"Local\", \"Regional\", \"Express\", \"Local\", \"Regional\", \"Regional\", \"Local\", \"Regional\", \"Express\", \"Express\", \"Local\", \"Local\", \"Local\", \"Regional\", \"Regional\", \"Express\", \"Regional\", \"Regional\", \"Regional\"),\n  stringsAsFactors = FALSE\n)\n\n# Map route types to colors\nroute_colors <- data.frame(\n  route_type = c(\"Regional\", \"Express\", \"Local\"),\n  color = IMPRINT,\n  stringsAsFactors = FALSE\n)\n\nroutes <- left_join(routes, route_colors, by = \"route_type\")\n\n# Merge station coordinates into routes\nroutes <- left_join(routes, stations %>% select(id, x, y), by = c(\"source_id\" = \"id\")) %>%\n  rename(x_start = x, y_start = y) %>%\n  left_join(stations %>% select(id, x, y), by = c(\"target_id\" = \"id\")) %>%\n  rename(x_end = x, y_end = y)\n\n# Calculate midpoint for edge labels and format label text\nroutes <- routes %>%\n  mutate(\n    x_mid = (x_start + x_end) / 2,\n    y_mid = (y_start + y_end) / 2,\n    label = paste0(route_id, \" | \", departure_time, \" → \", arrival_time)\n  )\n\n# --- Custom theme -----------------------------------------------------------\nanyplot_theme <- 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        = element_blank(),\n    panel.border      = element_blank(),\n    axis.title        = element_blank(),\n    axis.text         = element_blank(),\n    axis.ticks        = element_blank(),\n    plot.title        = element_text(color = INK, size = 24, hjust = 0.5, margin = margin(b = 20)),\n    legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT),\n    legend.text       = element_text(color = INK_SOFT, size = 16),\n    legend.title      = element_text(color = INK, size = 18),\n    plot.margin       = margin(20, 20, 20, 20)\n  )\n\n# --- Plot --------------------------------------------------------------------\np <- ggplot() +\n  # Draw edges with arrows\n  geom_segment(\n    data = routes,\n    aes(x = x_start, y = y_start, xend = x_end, yend = y_end, color = route_type),\n    arrow = arrow(length = unit(0.3, \"cm\"), type = \"closed\", angle = 20),\n    linewidth = 0.8,\n    alpha = 0.7\n  ) +\n  # Draw edge labels with background\n  geom_label(\n    data = routes,\n    aes(x = x_mid, y = y_mid, label = label),\n    size = 3.5,\n    color = INK,\n    fill = ELEVATED_BG,\n    label.padding = unit(0.3, \"lines\"),\n    label.size = 0.3,\n    label.r = unit(0.15, \"lines\"),\n    alpha = 0.85\n  ) +\n  # Draw stations as nodes\n  geom_point(\n    data = stations,\n    aes(x = x, y = y),\n    size = 8,\n    color = INK_SOFT,\n    fill = PAGE_BG,\n    stroke = 2,\n    shape = 21\n  ) +\n  # Draw station labels with subtle background\n  geom_label(\n    data = stations,\n    aes(x = x, y = y, label = label),\n    size = 4.5,\n    color = INK,\n    fill = ELEVATED_BG,\n    label.padding = unit(0.4, \"lines\"),\n    label.size = 0.2,\n    vjust = -1.2,\n    hjust = 0.5,\n    alpha = 0.9\n  ) +\n  # Scale colors for route types\n  scale_color_manual(\n    name = \"Route Type\",\n    values = c(\"Regional\" = IMPRINT[1], \"Express\" = IMPRINT[2], \"Local\" = IMPRINT[3])\n  ) +\n  coord_fixed(ratio = 1) +\n  labs(title = \"network-transport-static · r · ggplot2 · anyplot.ai\") +\n  anyplot_theme\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"}