{"spec_id":"area-stacked-percent","library":"altair","language":"python","code":"\"\"\" anyplot.ai\narea-stacked-percent: 100% Stacked Area Chart\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-12\n\"\"\"\n\nimport os\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\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# Okabe-Ito palette (first series always #009E73)\nIMPRINT = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\"]\n\n# Data - Energy source mix evolution\nnp.random.seed(42)\nyears = list(range(2015, 2025))\n\n# Evolving percentages showing energy transition (with slight variation for realism)\ncoal = [45, 42, 39, 35, 32, 28, 25, 22, 19, 16]\nnatural_gas = [25, 26, 27, 28, 29, 30, 31, 31, 30, 28]\nnuclear = [12, 12.5, 12, 11.5, 12, 12.5, 12, 11, 12.5, 12]\nrenewables = [18, 19.5, 22, 25.5, 27, 29.5, 32, 36, 36.5, 44]\n\n# Create DataFrame in long format for Altair\ndata = []\nfor i, year in enumerate(years):\n    data.append({\"Year\": year, \"Source\": \"Renewables\", \"Percentage\": renewables[i]})\n    data.append({\"Year\": year, \"Source\": \"Nuclear\", \"Percentage\": nuclear[i]})\n    data.append({\"Year\": year, \"Source\": \"Natural Gas\", \"Percentage\": natural_gas[i]})\n    data.append({\"Year\": year, \"Source\": \"Coal\", \"Percentage\": coal[i]})\n\ndf = pd.DataFrame(data)\n\n# Define stacking order (bottom to top)\nsource_order = [\"Coal\", \"Natural Gas\", \"Nuclear\", \"Renewables\"]\nstack_order = {\"Coal\": 1, \"Natural Gas\": 2, \"Nuclear\": 3, \"Renewables\": 4}\ndf[\"StackOrder\"] = df[\"Source\"].map(stack_order)\n\n# Plot - 100% Stacked Area Chart\nchart = (\n    alt.Chart(df)\n    .mark_area(opacity=0.85, line=alt.MarkConfig(strokeWidth=2))\n    .encode(\n        x=alt.X(\"Year:O\", title=\"Year\", axis=alt.Axis(labelFontSize=18, titleFontSize=22, labelAngle=0)),\n        y=alt.Y(\n            \"Percentage:Q\",\n            title=\"Share of Energy Mix (%)\",\n            stack=\"normalize\",\n            axis=alt.Axis(labelFontSize=18, titleFontSize=22, format=\".0%\"),\n        ),\n        color=alt.Color(\n            \"Source:N\",\n            scale=alt.Scale(domain=source_order, range=IMPRINT),\n            legend=alt.Legend(\n                title=\"Energy Source\",\n                titleFontSize=20,\n                labelFontSize=18,\n                orient=\"bottom\",\n                direction=\"horizontal\",\n                symbolSize=300,\n                symbolStrokeWidth=0,\n            ),\n        ),\n        order=alt.Order(\"StackOrder:Q\", sort=\"ascending\"),\n        tooltip=[\n            alt.Tooltip(\"Year:O\", title=\"Year\"),\n            alt.Tooltip(\"Source:N\", title=\"Source\"),\n            alt.Tooltip(\"Percentage:Q\", title=\"Share\", format=\".1f\"),\n        ],\n    )\n    .properties(\n        width=1600,\n        height=900,\n        title=alt.Title(text=\"area-stacked-percent · altair · anyplot.ai\", fontSize=28),\n        background=PAGE_BG,\n    )\n    .configure_view(fill=PAGE_BG, stroke=INK_SOFT)\n    .configure_axis(\n        domainColor=INK_SOFT, tickColor=INK_SOFT, gridColor=INK, gridOpacity=0.10, labelColor=INK_SOFT, titleColor=INK\n    )\n    .configure_title(color=INK)\n    .configure_legend(fillColor=ELEVATED_BG, strokeColor=INK_SOFT, labelColor=INK_SOFT, titleColor=INK)\n)\n\n# Save\nchart.save(f\"plot-{THEME}.png\", scale_factor=3.0)\nchart.save(f\"plot-{THEME}.html\")\n"}