{"spec_id":"curve-bias-variance-tradeoff","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\ncurve-bias-variance-tradeoff: Bias-Variance Tradeoff Curve\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-28\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Imprint palette — positions 1→3 for the three active curves; muted for the reference baseline\nC_BIAS = \"#009E73\"  # position 1 — green   (Bias²)\nC_VARIANCE = \"#C475FD\"  # position 2 — lavender (Variance)\nC_TOTAL = \"#4467A3\"  # position 3 — blue     (Total Error, the primary curve)\nC_IRREDUCIBLE = INK_MUTED  # theme-adaptive muted — constant noise floor reference\n\n# Data: theoretical bias-variance tradeoff curves\ncomplexity = np.linspace(0.1, 10, 100)\nbias_squared = 4 / (1 + complexity)\nvariance = 0.3 * complexity\nirreducible_error = np.ones_like(complexity) * 0.5\ntotal_error = bias_squared + variance + irreducible_error\n\noptimal_idx = np.argmin(total_error)\noptimal_complexity = complexity[optimal_idx]\noptimal_error = total_error[optimal_idx]\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Shaded zones (draw first so curves appear on top)\nax.axvspan(0, optimal_complexity, alpha=0.07, color=C_BIAS)\nax.axvspan(optimal_complexity, 10, alpha=0.07, color=C_VARIANCE)\n\n# Curves\nax.plot(complexity, bias_squared, color=C_BIAS, linewidth=2.5, linestyle=\"-\", zorder=3)\nax.plot(complexity, variance, color=C_VARIANCE, linewidth=2.5, linestyle=\"-\", zorder=3)\nax.plot(complexity, irreducible_error, color=C_IRREDUCIBLE, linewidth=2.0, linestyle=\"--\", zorder=2)\nax.plot(complexity, total_error, color=C_TOTAL, linewidth=3.5, linestyle=\"-\", zorder=4)\n\n# Optimal complexity marker\nax.axvline(x=optimal_complexity, color=INK_SOFT, linewidth=1.5, linestyle=\":\", alpha=0.7)\nax.scatter([optimal_complexity], [optimal_error], color=C_TOTAL, s=120, zorder=5, edgecolors=PAGE_BG, linewidths=1.5)\nax.annotate(\n    f\"Optimal\\n(≈{optimal_complexity:.1f})\",\n    xy=(optimal_complexity, optimal_error),\n    xytext=(optimal_complexity + 1.3, optimal_error + 0.75),\n    fontsize=8,\n    color=INK,\n    ha=\"left\",\n    va=\"bottom\",\n    arrowprops={\"arrowstyle\": \"->\", \"color\": INK_SOFT, \"lw\": 1.2},\n)\n\n# Zone labels (placed near the top of each shaded region)\nax.text(\n    optimal_complexity * 0.38,\n    4.5,\n    \"Underfitting\\n(High Bias)\",\n    fontsize=8,\n    ha=\"center\",\n    va=\"top\",\n    color=C_BIAS,\n    fontweight=\"bold\",\n)\nax.text(\n    (optimal_complexity + 10) * 0.5,\n    4.5,\n    \"Overfitting\\n(High Variance)\",\n    fontsize=8,\n    ha=\"center\",\n    va=\"top\",\n    color=C_VARIANCE,\n    fontweight=\"bold\",\n)\n\n# Direct curve labels (no legend needed — labels are placed on the curves)\nax.text(0.5, bias_squared[4] + 0.22, \"Bias²\", fontsize=8, color=C_BIAS, fontweight=\"bold\")\nax.text(8.2, variance[82] + 0.22, \"Variance\", fontsize=8, color=C_VARIANCE, fontweight=\"bold\")\nax.text(8.2, total_error[82] + 0.22, \"Total Error\", fontsize=8, color=C_TOTAL, fontweight=\"bold\")\nax.text(5.0, 0.62, \"Irreducible Error\", fontsize=8, ha=\"center\", color=C_IRREDUCIBLE, fontweight=\"bold\")\n\n# Formula annotation box (bottom right in axes coordinates)\nax.text(\n    0.98,\n    0.03,\n    \"Total Error = Bias² + Variance + Irreducible Error\",\n    transform=ax.transAxes,\n    fontsize=7,\n    ha=\"right\",\n    va=\"bottom\",\n    color=INK_SOFT,\n    bbox={\"boxstyle\": \"round,pad=0.4\", \"facecolor\": ELEVATED_BG, \"edgecolor\": INK_SOFT, \"alpha\": 0.9},\n)\n\n# Axes range and custom x-tick labels\nax.set_xlim(0, 10)\nax.set_ylim(0, 5)\nax.set_xticks([0.5, 5, 9.5])\nax.set_xticklabels([\"Low\", \"Medium\", \"High\"])\n\n# Style\ntitle = \"curve-bias-variance-tradeoff · python · matplotlib · anyplot.ai\"\ntitle_fontsize = max(8, round(12 * 67 / len(title))) if len(title) > 67 else 12\n\nax.set_xlabel(\"Model Complexity\", fontsize=10, color=INK)\nax.set_ylabel(\"Prediction Error\", fontsize=10, color=INK)\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT, labelcolor=INK_SOFT)\n\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor s in (\"left\", \"bottom\"):\n    ax.spines[s].set_color(INK_SOFT)\n\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\n\n# Save\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}