{"spec_id":"line-impurity-comparison","library":"muix","language":"javascript","code":"// anyplot.ai\n// line-impurity-comparison: Gini Impurity vs Entropy Comparison\n// Library: muix 7.29.1 | JavaScript 22.23.2\n// Quality: 91/100 | Created: 2026-08-26\n\nimport { LineChart } from \"@mui/x-charts/LineChart\";\nimport { ChartsReferenceLine } from \"@mui/x-charts/ChartsReferenceLine\";\nimport Box from \"@mui/material/Box\";\nimport Typography from \"@mui/material/Typography\";\n\nconst t = window.ANYPLOT_TOKENS;\n\n// --- Data (theoretical splitting-criterion curves over p in [0, 1]) --------\n// 101 points (step 0.01) so p=0.5 lands exactly on a sample — needed to mark\n// the shared peak on both curves, not just at the reference line.\nconst POINT_COUNT = 101;\nconst probabilities = Array.from({ length: POINT_COUNT }, (_, i) => i / (POINT_COUNT - 1));\n\n// Gini impurity: 2p(1-p) peaks at 0.5 (p=0.5). Scaled x2 so it shares the\n// same [0, 1] range as entropy and the two curves can be read off one axis.\nconst giniScaled = probabilities.map((p) => 4 * p * (1 - p));\n\n// Binary entropy in bits: -p*log2(p) - (1-p)*log2(1-p), already in [0, 1].\n// The 0*log2(0) term is undefined at p=0 and p=1, taken as its limit of 0.\nfunction binaryEntropy(p: number): number {\n  if (p <= 0 || p >= 1) return 0;\n  return -p * Math.log2(p) - (1 - p) * Math.log2(1 - p);\n}\nconst entropy = probabilities.map(binaryEntropy);\n\nconst TITLE_HEIGHT = 60;\n\n// --- Chart (default-exported component — the harness mounts it) -----------\nexport default function Chart() {\n  const { width, height } = window.ANYPLOT_SIZE;\n\n  return (\n    <Box\n      sx={{\n        width,\n        height,\n        display: \"flex\",\n        flexDirection: \"column\",\n        paddingTop: \"20px\",\n      }}\n    >\n      <Typography\n        sx={{\n          color: t.ink,\n          fontSize: 22,\n          fontWeight: 500,\n          textAlign: \"center\",\n          lineHeight: 1.2,\n        }}\n      >\n        line-impurity-comparison · javascript · muix · anyplot.ai\n      </Typography>\n      <LineChart\n        width={width}\n        height={height - TITLE_HEIGHT}\n        skipAnimation\n        colors={[t.palette[0], t.palette[1]]}\n        series={[\n          {\n            id: \"gini\",\n            data: giniScaled,\n            label: \"Gini impurity ×2 — 4p(1−p)\",\n            showMark: (params) => params.position === 0.5,\n            curve: \"natural\",\n            area: true,\n          },\n          {\n            id: \"entropy\",\n            data: entropy,\n            label: \"Entropy — −p·log₂p − (1−p)·log₂(1−p)\",\n            showMark: (params) => params.position === 0.5,\n            curve: \"natural\",\n            area: true,\n          },\n        ]}\n        xAxis={[\n          {\n            data: probabilities,\n            scaleType: \"linear\",\n            label: \"Probability of Class 1 (p)\",\n            min: 0,\n            max: 1,\n            valueFormatter: (v: number) => v.toFixed(2),\n            tickInterval: [0, 0.25, 0.5, 0.75, 1],\n          },\n        ]}\n        yAxis={[\n          {\n            label: \"Impurity (normalized)\",\n            min: 0,\n            max: 1.05,\n          },\n        ]}\n        grid={{ horizontal: true }}\n        margin={{ left: 90, right: 40, top: 30, bottom: 80 }}\n        sx={{\n          \"& .MuiChartsAxis-tickLabel\": { fontSize: \"14px\" },\n          \"& .MuiChartsAxis-label\": { fontSize: \"16px\" },\n          \"& .MuiChartsLegend-label\": { fontSize: \"14px\" },\n          \"& .MuiLineElement-root\": { strokeWidth: 3.5 },\n          // Two low-opacity area fills, gini drawn under entropy: where they\n          // overlap (0..gini(p)) the fills blend, while the uncovered band\n          // above (gini(p)..entropy(p)) reads as a single lavender wash —\n          // visually calling out where the two criteria diverge most.\n          \"& .MuiAreaElement-series-gini\": { fillOpacity: 0.22 },\n          \"& .MuiAreaElement-series-entropy\": { fillOpacity: 0.16 },\n          \"& .MuiMarkElement-root\": { strokeWidth: 2.5 },\n        }}\n      >\n        <ChartsReferenceLine\n          x={0.5}\n          label=\"Max impurity at p = 0.5\"\n          labelAlign=\"end\"\n          lineStyle={{ stroke: t.inkSoft, strokeDasharray: \"6 4\", strokeWidth: 1.5 }}\n          labelStyle={{ fill: t.inkSoft, fontSize: 13 }}\n        />\n      </LineChart>\n    </Box>\n  );\n}\n"}