{"spec_id":"curve-bias-variance-tradeoff","library":"echarts","language":"javascript","code":"// anyplot.ai\n// curve-bias-variance-tradeoff: Bias-Variance Tradeoff Curve\n// Library: echarts 6.1.0 | JavaScript 22.23.2\n// Quality: 89/100 | Created: 2026-08-24\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// model_complexity spans 1..20 (e.g. polynomial degree / tree depth)\nconst N = 60;\nconst complexity = Array.from({ length: N }, (_, i) => 1 + (i * 19) / (N - 1));\n\nconst biasSquared = complexity.map((c) => 4 / (1 + 0.55 * c) + 0.15);\nconst variance = complexity.map((c) => 0.012 * c * c + 0.03);\nconst irreducible = complexity.map(() => 0.35);\nconst totalError = complexity.map((_, i) => biasSquared[i] + variance[i] + irreducible[i]);\n\n// Find the optimal complexity (minimum total error)\nlet optIdx = 0;\nfor (let i = 1; i < N; i++) {\n  if (totalError[i] < totalError[optIdx]) optIdx = i;\n}\nconst optComplexity = complexity[optIdx];\nconst optError = totalError[optIdx];\n\n// --- Init ---------------------------------------------------------------\nconst chart = echarts.init(document.getElementById(\"container\"));\n\n// --- Option ---------------------------------------------------------------\nchart.setOption({\n  animation: false,\n  color: [t.palette[0], t.palette[2], t.palette[4], t.palette[6]],\n  backgroundColor: \"transparent\",\n  title: {\n    text: \"curve-bias-variance-tradeoff · javascript · echarts · anyplot.ai\",\n    left: \"center\",\n    top: 12,\n    textStyle: { color: t.ink, fontSize: 20, fontWeight: 500 },\n  },\n  grid: { left: 90, right: 170, top: 150, bottom: 90 },\n  legend: {\n    top: 60,\n    textStyle: { color: t.ink, fontSize: 15 },\n    itemWidth: 26,\n    itemHeight: 3,\n  },\n  xAxis: {\n    type: \"value\",\n    name: \"Model Complexity\",\n    nameLocation: \"middle\",\n    nameGap: 42,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    min: 1,\n    max: 20,\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { show: false },\n  },\n  yAxis: {\n    type: \"value\",\n    name: \"Prediction Error\",\n    nameLocation: \"middle\",\n    nameGap: 60,\n    nameTextStyle: { color: t.ink, fontSize: 16 },\n    min: 0,\n    axisLabel: { color: t.inkSoft, fontSize: 14 },\n    axisLine: { show: true, lineStyle: { color: t.inkSoft } },\n    axisTick: { show: false },\n    splitLine: { lineStyle: { color: t.grid } },\n  },\n  series: [\n    {\n      name: \"Bias²\",\n      type: \"line\",\n      data: complexity.map((c, i) => [c, biasSquared[i]]),\n      showSymbol: false,\n      lineStyle: { width: 3.5, color: t.palette[0] },\n      endLabel: {\n        show: true,\n        formatter: \"{a}\",\n        color: t.palette[0],\n        fontSize: 14,\n        fontWeight: 500,\n        distance: 10,\n        offset: [0, -16],\n      },\n      z: 3,\n      markArea: {\n        silent: true,\n        itemStyle: { color: t.palette[0], opacity: 0.1 },\n        label: { position: \"insideTop\", color: t.inkSoft, fontSize: 15 },\n        data: [[{ xAxis: 1, name: \"Underfitting zone\" }, { xAxis: optComplexity }]],\n      },\n    },\n    {\n      name: \"Variance\",\n      type: \"line\",\n      data: complexity.map((c, i) => [c, variance[i]]),\n      showSymbol: false,\n      lineStyle: { width: 3.5, color: t.palette[2] },\n      endLabel: {\n        show: true,\n        formatter: \"{a}\",\n        color: t.palette[2],\n        fontSize: 14,\n        fontWeight: 500,\n        distance: 10,\n      },\n      z: 3,\n      markArea: {\n        silent: true,\n        itemStyle: { color: t.palette[2], opacity: 0.1 },\n        label: { position: \"insideTop\", color: t.inkSoft, fontSize: 15 },\n        data: [[{ xAxis: optComplexity, name: \"Overfitting zone\" }, { xAxis: 20 }]],\n      },\n    },\n    {\n      name: \"Irreducible Error\",\n      type: \"line\",\n      data: complexity.map((c, i) => [c, irreducible[i]]),\n      showSymbol: false,\n      lineStyle: { width: 2.5, color: t.palette[6], type: \"dashed\" },\n      endLabel: {\n        show: true,\n        formatter: \"{a}\",\n        color: t.palette[6],\n        fontSize: 14,\n        fontWeight: 500,\n        distance: 10,\n        offset: [0, 16],\n      },\n      z: 2,\n    },\n    {\n      name: \"Total Error\",\n      type: \"line\",\n      data: complexity.map((c, i) => [c, totalError[i]]),\n      showSymbol: false,\n      lineStyle: { width: 4, color: t.palette[4] },\n      endLabel: {\n        show: true,\n        formatter: \"{a}\",\n        color: t.palette[4],\n        fontSize: 14,\n        fontWeight: 600,\n        distance: 10,\n      },\n      z: 4,\n      markLine: {\n        silent: true,\n        symbol: \"none\",\n        lineStyle: { color: t.ink, type: \"dashed\", width: 1.5 },\n        label: {\n          formatter: \"Optimal complexity\",\n          color: t.ink,\n          fontSize: 14,\n          position: \"insideEndTop\",\n        },\n        data: [{ xAxis: optComplexity }],\n      },\n      markPoint: {\n        silent: true,\n        symbol: \"circle\",\n        symbolSize: 14,\n        itemStyle: { color: t.palette[4], borderColor: t.pageBg, borderWidth: 2 },\n        label: { show: false },\n        data: [{ coord: [optComplexity, optError] }],\n      },\n    },\n  ],\n  graphic: [\n    {\n      type: \"text\",\n      left: 90,\n      top: 110,\n      style: {\n        text: \"Total Error = Bias² + Variance + Irreducible Error\",\n        fill: t.inkSoft,\n        fontSize: 15,\n        fontStyle: \"italic\",\n      },\n    },\n  ],\n});\n"}