{"spec_id":"histogram-stacked","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nhistogram-stacked: Stacked Histogram\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 90/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\n\n\nLetsPlot.setup_html()\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# Okabe-Ito palette - first series is always #009E73\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\"]\n\n# Data - Test scores from three different classes\nnp.random.seed(42)\n\n# Generate scores for three classes with different distributions\nclass_a = np.random.normal(loc=72, scale=10, size=150)  # Average performers\nclass_b = np.random.normal(loc=78, scale=8, size=120)  # Above average\nclass_c = np.random.normal(loc=68, scale=12, size=130)  # More varied\n\n# Combine into DataFrame\ndf = pd.DataFrame(\n    {\n        \"score\": np.concatenate([class_a, class_b, class_c]),\n        \"class\": [\"Class A\"] * 150 + [\"Class B\"] * 120 + [\"Class C\"] * 130,\n    }\n)\n\n# Clip scores to realistic range [0, 100]\ndf[\"score\"] = df[\"score\"].clip(0, 100)\n\n# Plot - Stacked histogram\nplot = (\n    ggplot(df, aes(x=\"score\", fill=\"class\"))\n    + geom_histogram(binwidth=5, position=\"stack\", color=PAGE_BG, size=0.3)\n    + scale_fill_manual(values=IMPRINT)\n    + labs(\n        x=\"Test Score (points)\", y=\"Number of Students\", title=\"histogram-stacked · letsplot · anyplot.ai\", fill=\"Class\"\n    )\n    + theme_minimal()\n    + theme(\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_grid_major=element_line(color=INK_SOFT, size=0.3),\n        axis_title=element_text(color=INK, size=20),\n        axis_text=element_text(color=INK_SOFT, size=16),\n        axis_line=element_line(color=INK_SOFT, size=0.5),\n        plot_title=element_text(color=INK, size=24, face=\"medium\"),\n        legend_title=element_text(color=INK, size=18),\n        legend_text=element_text(color=INK_SOFT, size=16),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        legend_position=\"right\",\n    )\n    + ggsize(1600, 900)\n)\n\n# Save as PNG (scale 3x for 4800x2700)\nggsave(plot, f\"plot-{THEME}.png\", scale=3, path=\".\")\n\n# Save interactive HTML\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}