{"spec_id":"line-impurity-comparison","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nline-impurity-comparison: Gini Impurity vs Entropy Comparison\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 93/100 | Updated: 2026-05-29\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport plotly.graph_objects as go\n\n\n# Theme tokens (Imprint palette + theme-adaptive chrome)\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\"\nGRID = \"rgba(26,26,23,0.15)\" if THEME == \"light\" else \"rgba(240,239,232,0.15)\"\n\n# Imprint categorical palette — positions 1 and 2\nGINI_COLOR = \"#009E73\"  # Imprint position 1 — brand green, always first series\nENTROPY_COLOR = \"#C475FD\"  # Imprint position 2 — lavender\n\n# Data\np = np.linspace(0, 1, 200)\n\ngini_raw = 2 * p * (1 - p)\ngini = gini_raw / gini_raw.max()\n\nentropy_raw = np.where((p == 0) | (p == 1), 0.0, -p * np.log2(p) - (1 - p) * np.log2(1 - p))\nentropy = entropy_raw / entropy_raw.max()\n\ntitle = \"line-impurity-comparison · python · plotly · anyplot.ai\"\ntitle_fontsize = 16  # len=55, under 67 baseline — no scaling needed\n\n# Plot\nfig = go.Figure()\n\n# Shaded region between curves to highlight divergence\nfig.add_trace(\n    go.Scatter(\n        x=np.concatenate([p, p[::-1]]),\n        y=np.concatenate([entropy, gini[::-1]]),\n        fill=\"toself\",\n        fillcolor=\"rgba(196,117,253,0.12)\",  # Imprint lavender at low opacity\n        line={\"width\": 0},\n        showlegend=False,\n        hoverinfo=\"skip\",\n    )\n)\n\n# Gini curve — Imprint position 1\nfig.add_trace(\n    go.Scatter(\n        x=p,\n        y=gini,\n        mode=\"lines\",\n        name=\"Gini: 2p(1−p) [scaled]\",\n        line={\"color\": GINI_COLOR, \"width\": 3.5},\n        hovertemplate=\"p = %{x:.2f}<br>Gini = %{y:.3f}<extra></extra>\",\n    )\n)\n\n# Entropy curve — Imprint position 2, dashed for distinction\nfig.add_trace(\n    go.Scatter(\n        x=p,\n        y=entropy,\n        mode=\"lines\",\n        name=\"Entropy: −p log₂p − (1−p) log₂(1−p)\",\n        line={\"color\": ENTROPY_COLOR, \"width\": 3.5, \"dash\": \"dash\"},\n        hovertemplate=\"p = %{x:.2f}<br>Entropy = %{y:.3f}<extra></extra>\",\n    )\n)\n\n# Annotation at p=0.5 maximum\nfig.add_annotation(\n    x=0.5,\n    y=1.0,\n    text=\"<b>Peak:</b> both measures = 1.0 at p = 0.5\",\n    showarrow=True,\n    arrowhead=2,\n    arrowsize=1.5,\n    arrowwidth=2,\n    arrowcolor=INK_SOFT,\n    ax=80,\n    ay=-55,\n    font={\"size\": 14, \"color\": INK},\n    bgcolor=ELEVATED_BG,\n    bordercolor=INK_SOFT,\n    borderwidth=1,\n    borderpad=7,\n)\n\n# Annotation highlighting divergence region\nmax_diff_idx = int(np.argmax(entropy - gini))\nfig.add_annotation(\n    x=p[max_diff_idx],\n    y=(entropy[max_diff_idx] + gini[max_diff_idx]) / 2,\n    text=\"<b>Divergence region</b><br>Entropy is wider than Gini\",\n    showarrow=True,\n    arrowhead=2,\n    arrowsize=1.2,\n    arrowwidth=2,\n    arrowcolor=INK_SOFT,\n    ax=110,\n    ay=60,\n    font={\"size\": 13, \"color\": INK},\n    bgcolor=ELEVATED_BG,\n    bordercolor=INK_SOFT,\n    borderwidth=1,\n    borderpad=6,\n)\n\n# Vertical reference line at p=0.5\nfig.add_vline(x=0.5, line_width=1.5, line_dash=\"dot\", line_color=INK_SOFT, opacity=0.3)\n\n# Style\nfig.update_layout(\n    autosize=False,\n    title={\"text\": title, \"font\": {\"size\": title_fontsize, \"color\": INK}, \"x\": 0.5, \"xanchor\": \"center\", \"y\": 0.97},\n    xaxis={\n        \"title\": {\"text\": \"Probability (p)\", \"font\": {\"size\": 12, \"color\": INK}},\n        \"tickfont\": {\"size\": 10, \"color\": INK_SOFT},\n        \"range\": [-0.02, 1.02],\n        \"dtick\": 0.1,\n        \"showgrid\": True,\n        \"gridcolor\": GRID,\n        \"gridwidth\": 1,\n        \"showline\": True,\n        \"linecolor\": INK_SOFT,\n        \"linewidth\": 1.5,\n        \"zeroline\": False,\n        \"mirror\": False,\n    },\n    yaxis={\n        \"title\": {\"text\": \"Impurity Measure (normalized)\", \"font\": {\"size\": 12, \"color\": INK}},\n        \"tickfont\": {\"size\": 10, \"color\": INK_SOFT},\n        \"range\": [-0.02, 1.08],\n        \"dtick\": 0.2,\n        \"showgrid\": True,\n        \"gridcolor\": GRID,\n        \"gridwidth\": 1,\n        \"showline\": True,\n        \"linecolor\": INK_SOFT,\n        \"linewidth\": 1.5,\n        \"zeroline\": False,\n        \"mirror\": False,\n    },\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    font={\"color\": INK},\n    template=\"plotly_white\",\n    legend={\n        \"font\": {\"size\": 10, \"color\": INK_SOFT},\n        \"x\": 0.5,\n        \"y\": 0.02,\n        \"xanchor\": \"center\",\n        \"yanchor\": \"bottom\",\n        \"bgcolor\": ELEVATED_BG,\n        \"bordercolor\": INK_SOFT,\n        \"borderwidth\": 1,\n    },\n    margin={\"l\": 80, \"r\": 40, \"t\": 80, \"b\": 60},\n)\n\n# Save\nfig.write_image(f\"plot-{THEME}.png\", width=800, height=450, scale=4)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}