{"spec_id":"curve-bias-variance-tradeoff","library":"ggplot2","language":"r","code":"#' anyplot.ai\n#' curve-bias-variance-tradeoff: Bias-Variance Tradeoff Curve\n#' Library: ggplot2 3.5.1 | R 4.4.1\n#' Quality: 92/100 | Created: 2026-05-28\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\"\nINK         <- if (THEME == \"light\") \"#1A1A17\" else \"#F0EFE8\"\nINK_SOFT    <- if (THEME == \"light\") \"#4A4A44\" else \"#B8B7B0\"\nINK_MUTED   <- if (THEME == \"light\") \"#6B6A63\" else \"#A8A79F\"\nELEVATED_BG <- if (THEME == \"light\") \"#FFFDF6\" else \"#242420\"\n\nIMPRINT_PALETTE <- c(\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\")\n\n# --- Data ---\nn            <- 100\ncomplexity   <- seq(1, 10, length.out = n)\nirreducible  <- rep(0.15, n)\nbias_squared <- 0.70 * exp(-0.5 * (complexity - 1))\nvariance     <- 0.70 * exp(-0.5 * (10 - complexity))\ntotal_error  <- bias_squared + variance + irreducible\n\noptimal_idx <- which.min(total_error)\noptimal_x   <- complexity[optimal_idx]\noptimal_y   <- total_error[optimal_idx]\n\nbias_ann_y <- bias_squared[which.min(abs(complexity - 1.4))] + 0.04\nvar_ann_y  <- variance[which.min(abs(complexity - 8.5))] + 0.04\ntot_ann_y  <- total_error[which.min(abs(complexity - 3.0))] + 0.05\n\n# --- Long format ---\ncomponents <- c(\"Bias²\", \"Variance\", \"Total Error\", \"Irreducible Error\")\ndf_long <- data.frame(\n    complexity = rep(complexity, 4),\n    error      = c(bias_squared, variance, total_error, irreducible),\n    component  = factor(rep(components, each = n), levels = components)\n)\n\ncurve_colors    <- setNames(IMPRINT_PALETTE, components)\ncurve_linetypes <- c(\"Bias²\" = \"solid\", \"Variance\" = \"longdash\",\n                     \"Total Error\" = \"solid\", \"Irreducible Error\" = \"dotted\")\ncurve_lwidths   <- c(\"Bias²\" = 1.0, \"Variance\" = 1.0,\n                     \"Total Error\" = 1.7, \"Irreducible Error\" = 0.9)\n\ntitle_str <- \"curve-bias-variance-tradeoff · r · ggplot2 · anyplot.ai\"\n\n# --- Plot ---\np <- ggplot(df_long,\n            aes(x = complexity, y = error,\n                color = component, linetype = component,\n                linewidth = component)) +\n    annotate(\"rect\", xmin = 1, xmax = optimal_x,\n             ymin = -Inf, ymax = Inf, fill = \"#009E73\", alpha = 0.05) +\n    annotate(\"rect\", xmin = optimal_x, xmax = 10,\n             ymin = -Inf, ymax = Inf, fill = \"#AE3030\", alpha = 0.05) +\n    geom_vline(xintercept = optimal_x, color = INK_SOFT,\n               linetype = \"dashed\", linewidth = 0.5) +\n    geom_line() +\n    scale_color_manual(values = curve_colors) +\n    scale_linetype_manual(values = curve_linetypes) +\n    scale_linewidth_manual(values = curve_lwidths) +\n    annotate(\"text\", x = (1 + optimal_x) / 2, y = 0.86,\n             label = \"Underfitting\", color = INK_MUTED, size = 3.0) +\n    annotate(\"text\", x = (optimal_x + 10) / 2, y = 0.86,\n             label = \"Overfitting\", color = INK_MUTED, size = 3.0) +\n    annotate(\"text\", x = optimal_x + 0.2, y = optimal_y - 0.04,\n             label = \"Optimal\", color = INK_SOFT, size = 2.8, hjust = 0) +\n    annotate(\"text\", x = 1.4, y = bias_ann_y,\n             label = \"Bias²\", color = IMPRINT_PALETTE[1],\n             size = 3.2, hjust = 0, fontface = \"bold\") +\n    annotate(\"text\", x = 8.5, y = var_ann_y,\n             label = \"Variance\", color = IMPRINT_PALETTE[2],\n             size = 3.2, hjust = 0.5, fontface = \"bold\") +\n    annotate(\"text\", x = 3.0, y = tot_ann_y,\n             label = \"Total Error\", color = IMPRINT_PALETTE[3],\n             size = 3.0, hjust = 0.5, fontface = \"bold\") +\n    annotate(\"text\", x = 7.0, y = 0.10,\n             label = \"Irreducible Error\", color = IMPRINT_PALETTE[4],\n             size = 2.8, hjust = 0.5) +\n    scale_x_continuous(\n        breaks = c(1, optimal_x, 10),\n        labels = c(\"Low\", \"Optimal\", \"High\"),\n        expand = c(0.02, 0)\n    ) +\n    scale_y_continuous(expand = c(0.02, 0)) +\n    labs(\n        title    = title_str,\n        subtitle = \"Total Error = Bias² + Variance + Irreducible Error\",\n        x        = \"Model Complexity\",\n        y        = \"Prediction Error\"\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.y = element_line(color = INK, linewidth = 0.15),\n        panel.grid.major.x = element_blank(),\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        axis.line          = element_line(color = INK_SOFT, linewidth = 0.4),\n        plot.title         = element_text(color = INK, size = 12, face = \"bold\"),\n        plot.subtitle      = element_text(color = INK_MUTED, size = 8),\n        legend.position    = \"none\",\n        plot.margin        = margin(15, 20, 15, 15)\n    )\n\n# --- Save ---\nggsave(\n    filename = sprintf(\"plot-%s.png\", THEME),\n    plot     = p,\n    device   = ragg::agg_png,\n    width    = 8,\n    height   = 4.5,\n    units    = \"in\",\n    dpi      = 400\n)\n"}