{"spec_id":"curve-bias-variance-tradeoff","library":"makie","language":"julia","code":"# anyplot.ai\n# curve-bias-variance-tradeoff: Bias-Variance Tradeoff Curve\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 89/100 | Created: 2026-05-28\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# Theme tokens\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst INK_MUTED   = THEME == \"light\" ? colorant\"#6B6A63\" : colorant\"#A8A79F\"\n\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 — brand green (Bias²)\n    colorant\"#C475FD\",  # 2 — lavender (Variance)\n    colorant\"#4467A3\",  # 3 — blue (Total Error)\n    colorant\"#BD8233\",  # 4 — ochre (Irreducible Error)\n]\n\n# Data — theoretical bias-variance tradeoff curves\ncomplexity = range(0.1, 10.0, length=80)\n\nbias_sq         = 1.0 ./ (1.0 .+ complexity) .+ 0.02\nvariance        = (complexity .^ 1.4) ./ 22.0\nirreducible_err = fill(0.15, length(complexity))\ntotal_err       = bias_sq .+ variance .+ irreducible_err\n\n# Find optimal complexity (minimum total error)\nopt_idx       = argmin(total_err)\nopt_complexity = complexity[opt_idx]\nopt_total      = total_err[opt_idx]\n\n# Title\ntitle_str = \"curve-bias-variance-tradeoff · julia · makie · anyplot.ai\"\nn = length(title_str)\ndefault_titlesize = 20.0\ntitlesize = n > 67 ? max(14.0, round(default_titlesize * 67 / n)) : default_titlesize\n\n# Plot\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = title_str,\n    titlesize          = titlesize,\n    titlecolor         = INK,\n    xlabel             = \"Model Complexity\",\n    ylabel             = \"Prediction Error\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridvisible       = false,\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    yminorgridvisible  = false,\n    xminorgridvisible  = false,\n)\n\n# Shaded zones (underfitting / overfitting)\nvspan!(ax, complexity[1], opt_complexity;\n    color = RGBAf(IMPRINT_PALETTE[1].r, IMPRINT_PALETTE[1].g, IMPRINT_PALETTE[1].b, 0.07))\nvspan!(ax, opt_complexity, complexity[end];\n    color = RGBAf(IMPRINT_PALETTE[2].r, IMPRINT_PALETTE[2].g, IMPRINT_PALETTE[2].b, 0.07))\n\n# Curves\nlines!(ax, complexity, bias_sq;\n    color = IMPRINT_PALETTE[1], linewidth = 2.5, linestyle = :solid, label = \"Bias²\")\nlines!(ax, complexity, variance;\n    color = IMPRINT_PALETTE[2], linewidth = 2.5, linestyle = :dash, label = \"Variance\")\nlines!(ax, complexity, total_err;\n    color = IMPRINT_PALETTE[3], linewidth = 3.0, linestyle = :dashdot, label = \"Total Error\")\nlines!(ax, complexity, irreducible_err;\n    color = IMPRINT_PALETTE[4], linewidth = 2.0, linestyle = :dot, label = \"Irreducible Error\")\n\n# Optimal point vertical line\nvlines!(ax, [opt_complexity]; color = INK_SOFT, linewidth = 1.5, linestyle = :dash)\n\n# Optimal point marker on total error curve\nscatter!(ax, [opt_complexity], [opt_total];\n    color = IMPRINT_PALETTE[3], markersize = 14, strokewidth = 1.5,\n    strokecolor = PAGE_BG)\n\n# Zone labels\ntext!(ax, complexity[4], maximum(total_err) * 0.78;\n    text = \"Underfitting\\n(High Bias)\",\n    color = INK_MUTED, fontsize = 13, align = (:left, :center))\ntext!(ax, opt_complexity + 0.3, maximum(total_err) * 0.78;\n    text = \"Overfitting\\n(High Variance)\",\n    color = INK_MUTED, fontsize = 13, align = (:left, :center))\n\n# Optimal label\ntext!(ax, opt_complexity, opt_total + 0.03;\n    text = \"Optimal\",\n    color = INK, fontsize = 11, align = (:center, :bottom), font = :bold)\n\n# Direct curve labels (spec requirement: annotate each curve directly on the plot)\nlbl_bias_x   = 2.0\nlbl_bias_y   = 1.0 / (1.0 + lbl_bias_x) + 0.02\nlbl_var_x    = 8.5\nlbl_var_y    = (lbl_var_x ^ 1.4) / 22.0\nlbl_tot_x    = 7.5\nlbl_tot_y    = (1.0 / (1.0 + lbl_tot_x) + 0.02) + ((lbl_tot_x ^ 1.4) / 22.0) + 0.15\nlbl_irr_x    = 5.0\n\ntext!(ax, lbl_bias_x, lbl_bias_y + 0.03;\n    text = \"Bias²\",\n    color = IMPRINT_PALETTE[1], fontsize = 12, align = (:center, :bottom), font = :bold)\ntext!(ax, lbl_var_x, lbl_var_y + 0.03;\n    text = \"Variance\",\n    color = IMPRINT_PALETTE[2], fontsize = 12, align = (:center, :bottom), font = :bold)\ntext!(ax, lbl_tot_x, lbl_tot_y + 0.03;\n    text = \"Total Error\",\n    color = IMPRINT_PALETTE[3], fontsize = 12, align = (:center, :bottom), font = :bold)\ntext!(ax, lbl_irr_x, 0.15 + 0.03;\n    text = \"Irreducible Error\",\n    color = IMPRINT_PALETTE[4], fontsize = 12, align = (:center, :bottom), font = :bold)\n\n# Formula annotation\ntext!(ax, complexity[end], irreducible_err[1] + 0.01;\n    text = \"Total Error = Bias² + Variance + Irreducible Error\",\n    color = INK_MUTED, fontsize = 12, align = (:right, :bottom))\n\n# Legend\naxislegend(ax;\n    position       = :rc,\n    backgroundcolor = ELEVATED_BG,\n    framecolor     = INK_SOFT,\n    labelcolor     = INK,\n    titlecolor     = INK,\n    framewidth     = 0.8,\n    labelsize      = 12,\n)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}