{"spec_id":"polar-scatter","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' polar-scatter: Polar Scatter Plot\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 89/100 | Created: 2026-09-05\n\nlibrary(ggplot2)\nlibrary(scales)\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\nIMPRINT_PALETTE <- c(\n  \"#009E73\", # 1 — brand green\n  \"#C475FD\", # 2 — lavender\n  \"#4467A3\", # 3 — blue\n  \"#BD8233\"  # 4 — ochre\n)\n\n# --- Data: wind speed and direction observations by time of day -------------\nperiods    <- c(\"Morning\", \"Afternoon\", \"Evening\", \"Night\")\nn_per      <- c(40, 35, 35, 20)\ndir_mean   <- c(50, 210, 170, 300)  # prevailing bearing per period, degrees\ndir_sd     <- c(20, 25, 30, 35)\nspeed_mean <- c(9, 15, 11, 6)       # m/s\nspeed_sd   <- c(2, 3, 2.5, 1.5)\n\nn_total <- sum(n_per)\nperiod      <- factor(rep(periods, times = n_per), levels = periods)\ntheta       <- (rnorm(n_total, rep(dir_mean, times = n_per), rep(dir_sd, times = n_per))) %% 360\nwind_speed  <- pmax(rnorm(n_total, rep(speed_mean, times = n_per), rep(speed_sd, times = n_per)), 0.5)\n\nwind_obs <- tibble::tibble(theta = theta, wind_speed = wind_speed, period = period)\n\nradius_max <- max(wind_obs$wind_speed) * 1.15\n\n# --- Theme --------------------------------------------------------------------\ngrid_major <- scales::alpha(INK, 0.15)\ngrid_minor <- scales::alpha(INK, 0.08)\n\nanyplot_theme <- theme_minimal(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    panel.grid.major  = element_line(color = grid_major, linewidth = 0.3),\n    panel.grid.minor  = element_line(color = grid_minor, linewidth = 0.15),\n    axis.ticks        = element_blank(),\n    axis.title.x      = element_blank(),\n    axis.title.y      = element_text(color = INK, size = 10),\n    axis.text         = element_text(color = INK_SOFT, size = 8),\n    axis.text.y       = element_text(color = INK_SOFT, size = 8, margin = margin(r = 8)),\n    plot.title        = element_text(color = INK, size = 12, face = \"bold\"),\n    plot.subtitle     = element_text(color = INK_SOFT, size = 9),\n    legend.background = element_rect(fill = ELEVATED_BG, color = NA),\n    legend.text       = element_text(color = INK_SOFT, size = 8),\n    legend.title      = element_text(color = INK, size = 10)\n  )\n\n# --- Plot ---------------------------------------------------------------------\np <- ggplot(wind_obs, aes(x = theta, y = wind_speed, fill = period)) +\n  geom_point(shape = 21, size = 3.0, stroke = 0.4, color = PAGE_BG, alpha = 0.75) +\n  scale_x_continuous(\n    limits = c(0, 360),\n    breaks = c(0, 90, 180, 270),\n    labels = c(\"0° N\", \"90° E\", \"180° S\", \"270° W\"),\n    expand = c(0, 0)\n  ) +\n  scale_y_continuous(\n    limits = c(0, radius_max),\n    expand = expansion(mult = c(0, 0.05))\n  ) +\n  scale_fill_manual(values = IMPRINT_PALETTE, name = \"Time of Day\") +\n  coord_polar(theta = \"x\", start = 0, direction = 1) +\n  labs(\n    title = \"Wind Observations · polar-scatter · r · ggplot2 · anyplot.ai\",\n    subtitle = \"Each time of day carries a distinct prevailing wind direction and speed band\",\n    y = \"Wind Speed (m/s)\"\n  ) +\n  anyplot_theme\n\n# --- Save -----------------------------------------------------------------\nggsave(\n  filename = sprintf(\"plot-%s.png\", THEME),\n  plot     = p,\n  device   = ragg::agg_png,\n  width    = 6,\n  height   = 6,\n  units    = \"in\",\n  dpi      = 400\n)\n"}