{"spec_id":"learning-curve-basic","library":"chartjs","language":"javascript","code":"// anyplot.ai\n// learning-curve-basic: Model Learning Curve\n// Library: chartjs 4.4.7 | JavaScript 22.23.2\n// Quality: 91/100 | Created: 2026-09-05\n\n//# anyplot-orientation: landscape\nconst t = window.ANYPLOT_TOKENS;\n\nfunction hexToRgba(hex, alpha) {\n  const r = parseInt(hex.slice(1, 3), 16);\n  const g = parseInt(hex.slice(3, 5), 16);\n  const b = parseInt(hex.slice(5, 7), 16);\n  return `rgba(${r}, ${g}, ${b}, ${alpha})`;\n}\n\n// --- Data (in-memory, deterministic) ----------------------------------------\n// Digit-classifier learning curve: mean +/- 1 std across 8 cross-validation\n// folds, evaluated at 10 training-set sizes.\nconst trainSizes = [90, 180, 360, 540, 720, 900, 1080, 1260, 1440, 1617];\nconst trainMean = [0.999, 0.998, 0.995, 0.992, 0.99, 0.988, 0.987, 0.986, 0.985, 0.984];\nconst trainStd = [0.002, 0.003, 0.004, 0.004, 0.005, 0.005, 0.005, 0.005, 0.005, 0.005];\nconst valMean = [0.87, 0.905, 0.928, 0.941, 0.949, 0.954, 0.958, 0.961, 0.963, 0.965];\nconst valStd = [0.035, 0.03, 0.025, 0.022, 0.02, 0.018, 0.017, 0.016, 0.015, 0.015];\n\nconst trainUpper = trainMean.map((m, i) => m + trainStd[i]);\nconst trainLower = trainMean.map((m, i) => m - trainStd[i]);\nconst valUpper = valMean.map((m, i) => m + valStd[i]);\nconst valLower = valMean.map((m, i) => m - valStd[i]);\n\nconst trainColor = t.palette[0]; // brand green\nconst valColor = t.palette[1]; // lavender\n\n// --- Mount -------------------------------------------------------------------\nconst canvas = document.createElement(\"canvas\");\ndocument.getElementById(\"container\").appendChild(canvas);\n\n// --- Chart ---------------------------------------------------------------\n// Confidence bands are drawn first (as fill-only line pairs, hidden from the\n// legend), then the mean lines are drawn on top so the bands sit behind them.\nnew Chart(canvas, {\n  type: \"line\",\n  data: {\n    labels: trainSizes,\n    datasets: [\n      {\n        label: \"Training ±1 SD\",\n        data: trainUpper,\n        borderWidth: 0,\n        pointRadius: 0,\n        fill: false,\n        tension: 0.3,\n      },\n      {\n        label: \"Training ±1 SD\",\n        data: trainLower,\n        borderWidth: 0,\n        pointRadius: 0,\n        backgroundColor: hexToRgba(trainColor, 0.18),\n        fill: \"-1\",\n        tension: 0.3,\n      },\n      {\n        label: \"Validation ±1 SD\",\n        data: valUpper,\n        borderWidth: 0,\n        pointRadius: 0,\n        fill: false,\n        tension: 0.3,\n      },\n      {\n        label: \"Validation ±1 SD\",\n        data: valLower,\n        borderWidth: 0,\n        pointRadius: 0,\n        backgroundColor: hexToRgba(valColor, 0.18),\n        fill: \"-1\",\n        tension: 0.3,\n      },\n      {\n        label: \"Training score\",\n        data: trainMean,\n        borderColor: trainColor,\n        backgroundColor: trainColor,\n        pointBackgroundColor: trainColor,\n        borderWidth: 3.5,\n        pointRadius: 5,\n        fill: false,\n        tension: 0.3,\n      },\n      {\n        label: \"Validation score\",\n        data: valMean,\n        borderColor: valColor,\n        backgroundColor: valColor,\n        pointBackgroundColor: valColor,\n        borderWidth: 3.5,\n        pointRadius: 5,\n        fill: false,\n        tension: 0.3,\n      },\n    ],\n  },\n  options: {\n    responsive: true,\n    maintainAspectRatio: false,\n    animation: false,\n    plugins: {\n      title: {\n        display: true,\n        text: \"learning-curve-basic · javascript · chartjs · anyplot.ai\",\n        color: t.ink,\n        font: { size: 22 },\n      },\n      legend: {\n        labels: {\n          color: t.ink,\n          font: { size: 16 },\n          filter: (item) => !item.text.includes(\"±1 SD\"),\n        },\n      },\n    },\n    scales: {\n      x: {\n        ticks: { color: t.inkSoft, font: { size: 14 } },\n        grid: { color: t.grid },\n        title: { display: true, text: \"Training Set Size (samples)\", color: t.ink, font: { size: 16 } },\n      },\n      y: {\n        min: 0.8,\n        max: 1.0,\n        ticks: { color: t.inkSoft, font: { size: 14 } },\n        grid: { color: t.grid },\n        title: { display: true, text: \"Cross-Validation Accuracy\", color: t.ink, font: { size: 16 } },\n      },\n    },\n  },\n});\n"}