{"spec_id":"scatter-complex-plane","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' scatter-complex-plane: Complex Plane Visualization (Argand Diagram)\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 82/100 | Created: 2026-06-02\n\nlibrary(ggplot2)\nlibrary(ragg)\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 (5th roots of unity)\n    \"#C475FD\",  # 2 — lavender (arbitrary points)\n    \"#4467A3\",  # 3 — blue\n    \"#BD8233\",  # 4 — ochre\n    \"#AE3030\",  # 5 — matte red\n    \"#2ABCCD\",  # 6 — cyan\n    \"#954477\",  # 7 — rose\n    \"#99B314\"   # 8 — lime\n)\n\nGRID_COLOR <- adjustcolor(INK, alpha.f = 0.12)\n\n# Data: 5th roots of unity (z^5 = 1, evenly spaced on the unit circle)\nn      <- 5\nangles <- 2 * pi * (0:(n - 1)) / n\n\nunity_real <- cos(angles)\nunity_imag <- sin(angles)\n\n# Rectangular form labels: a + bi (inlined)\nunity_labels <- mapply(\n    function(r, i) if (i >= 0) sprintf(\"%.2f + %.2fi\", r, i) else sprintf(\"%.2f - %.2fi\", r, abs(i)),\n    unity_real, unity_imag\n)\n\n# Two arbitrary complex numbers outside the unit circle\narb_real   <- c( 1.30,  -0.60)\narb_imag   <- c( 0.70,  -1.40)\narb_angles <- atan2(arb_imag, arb_real)\narb_labels <- mapply(\n    function(r, i) if (i >= 0) sprintf(\"%.2f + %.2fi\", r, i) else sprintf(\"%.2f - %.2fi\", r, abs(i)),\n    arb_real, arb_imag\n)\n\n# Combined data frame\ndf <- data.frame(\n    real     = c(unity_real, arb_real),\n    imag     = c(unity_imag, arb_imag),\n    label    = c(unity_labels, arb_labels),\n    angle    = c(angles, arb_angles),\n    category = factor(\n        c(rep(\"5th Roots of Unity\", n), rep(\"Arbitrary Points\", 2)),\n        levels = c(\"5th Roots of Unity\", \"Arbitrary Points\")\n    ),\n    stringsAsFactors = FALSE\n)\n\n# Nudge labels outward from origin for readability\nnudge_scale <- 0.30\ndf$nx <- cos(df$angle) * nudge_scale\ndf$ny <- sin(df$angle) * nudge_scale\n# Per-point hjust: left-align rightward labels so text clears the arrowhead\ndf$hjust <- ifelse(cos(df$angle) > 0.8, 0, ifelse(cos(df$angle) < -0.8, 1, 0.5))\n\n# Unit circle reference path\ntheta_seq <- seq(0, 2 * pi, length.out = 300)\ncircle_df <- data.frame(x = cos(theta_seq), y = sin(theta_seq))\n\n# Title (48 chars — below 67-char baseline, no font shrink needed)\ntitle_str  <- \"scatter-complex-plane · r · ggplot2 · anyplot.ai\"\ntitle_size <- max(8, round(12 * 67 / max(nchar(title_str), 67)))\n\ncategory_colors <- c(\n    \"5th Roots of Unity\" = IMPRINT_PALETTE[1],\n    \"Arbitrary Points\"   = IMPRINT_PALETTE[2]\n)\n\np <- ggplot() +\n    # Unit circle (dashed reference)\n    geom_path(\n        data = circle_df, aes(x = x, y = y),\n        color = INK_SOFT, linetype = \"dashed\", linewidth = 0.5\n    ) +\n    # Origin axes (horizontal and vertical lines through 0)\n    geom_hline(yintercept = 0, color = INK_SOFT, linewidth = 0.5) +\n    geom_vline(xintercept = 0, color = INK_SOFT, linewidth = 0.5) +\n    # Vectors: arrows from origin to each complex number\n    geom_segment(\n        data = df,\n        aes(x = 0, y = 0, xend = real, yend = imag, color = category),\n        arrow     = arrow(length = unit(0.12, \"inches\"), type = \"closed\"),\n        linewidth  = 0.9,\n        alpha     = 0.85\n    ) +\n    # Points\n    geom_point(\n        data = df,\n        aes(x = real, y = imag, color = category),\n        size = 3.5\n    ) +\n    # Labels: rectangular form (a + bi), nudged outward from origin\n    geom_text(\n        data = df,\n        aes(x = real + nx, y = imag + ny, label = label, color = category, hjust = hjust),\n        size        = 3.2,\n        show.legend = FALSE\n    ) +\n    scale_color_manual(values = category_colors, name = NULL) +\n    coord_equal(xlim = c(-2.1, 2.1), ylim = c(-2.1, 2.1)) +\n    labs(\n        title = title_str,\n        x     = \"Real\",\n        y     = \"Imaginary\"\n    ) +\n    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_COLOR, linewidth = 0.3),\n        panel.grid.minor  = element_blank(),\n        panel.border      = element_blank(),\n        axis.title        = element_text(color = INK, size = 10),\n        axis.text         = element_text(color = INK_SOFT, size = 8),\n        plot.title        = element_text(color = INK, size = title_size, face = \"bold\"),\n        legend.background = element_rect(fill = ELEVATED_BG, color = INK_SOFT, linewidth = 0.3),\n        legend.text       = element_text(color = INK_SOFT, size = 8),\n        legend.position   = \"bottom\",\n        plot.margin       = margin(t = 20, r = 20, b = 20, l = 20)\n    )\n\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"}