{"spec_id":"line-impurity-comparison","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nline-impurity-comparison: Gini Impurity vs Entropy Comparison\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 88/100 | Updated: 2026-05-29\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    annotate,\n    element_blank,\n    element_line,\n    element_rect,\n    element_text,\n    geom_line,\n    geom_point,\n    geom_vline,\n    ggplot,\n    labs,\n    scale_color_manual,\n    scale_linetype_manual,\n    scale_x_continuous,\n    scale_y_continuous,\n    theme,\n    theme_minimal,\n)\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\"\n\n# Imprint palette positions 1 and 2\nGINI_COLOR = \"#009E73\"  # Imprint palette position 1 — brand green, always first series\nENTROPY_COLOR = \"#C475FD\"  # Imprint palette position 2 — lavender\n\n# Data\np = np.linspace(0, 1, 200)\ngini = 2 * p * (1 - p)\nentropy = np.where((p > 0) & (p < 1), -p * np.log2(p) - (1 - p) * np.log2(1 - p), 0.0)\n\nGINI_LABEL = \"Gini: 2p(1−p)\"\nENTROPY_LABEL = \"Entropy: −p log₂p − (1−p) log₂(1−p)\"\n\ndf = pd.DataFrame(\n    {\n        \"p\": np.tile(p, 2),\n        \"impurity\": np.concatenate([gini, entropy]),\n        \"measure\": [GINI_LABEL] * len(p) + [ENTROPY_LABEL] * len(p),\n    }\n)\n\nmaxima = pd.DataFrame({\"p\": [0.5, 0.5], \"impurity\": [0.5, 1.0], \"measure\": [GINI_LABEL, ENTROPY_LABEL]})\n\n# Title with length-scaled fontsize (baseline: 67 chars → 12pt)\ntitle = \"line-impurity-comparison · python · plotnine · anyplot.ai\"\nn = len(title)\ntitle_fontsize = max(8, round(12 * (67 / n if n > 67 else 1.0)))\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"p\", y=\"impurity\", color=\"measure\", linetype=\"measure\"))\n    + geom_vline(xintercept=0.5, color=INK_SOFT, size=0.6, linetype=\"dashed\", alpha=0.5)\n    + geom_line(size=2.5)\n    + geom_point(data=maxima, size=5, show_legend=False)\n    + annotate(\n        \"text\", x=0.5, y=1.07, label=\"Both maxima at p = 0.5\", size=5.5, ha=\"center\", color=INK_SOFT, fontstyle=\"italic\"\n    )\n    + scale_color_manual(values={GINI_LABEL: GINI_COLOR, ENTROPY_LABEL: ENTROPY_COLOR})\n    + scale_linetype_manual(values={GINI_LABEL: \"solid\", ENTROPY_LABEL: \"dashed\"})\n    + scale_x_continuous(breaks=np.arange(0, 1.1, 0.1))\n    + scale_y_continuous(breaks=np.arange(0, 1.1, 0.2), limits=(0, 1.15))\n    + labs(\n        x=\"Probability (p)\",\n        y=\"Impurity Measure (normalized)\",\n        title=title,\n        color=\"Splitting Criterion\",\n        linetype=\"Splitting Criterion\",\n    )\n    + theme_minimal()\n    + theme(\n        figure_size=(8, 4.5),\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        text=element_text(size=7),\n        axis_title=element_text(size=10, color=INK),\n        axis_text=element_text(size=8, color=INK_SOFT),\n        plot_title=element_text(size=title_fontsize, color=INK),\n        legend_text=element_text(size=8, color=INK_SOFT),\n        legend_title=element_text(size=9, color=INK, weight=\"bold\"),\n        legend_position=(0.15, 0.78),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        legend_key=element_blank(),\n        panel_grid_major_x=element_blank(),\n        panel_grid_minor=element_blank(),\n        panel_grid_major_y=element_line(color=INK, size=0.3, alpha=0.15),\n        axis_line=element_line(color=INK_SOFT, size=0.8),\n    )\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=400, width=8, height=4.5, units=\"in\", verbose=False)\n"}