{"spec_id":"area-stacked-confidence","library":"altair","language":"python","code":"\"\"\" anyplot.ai\narea-stacked-confidence: Stacked Area Chart with Confidence Bands\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-05-18\n\"\"\"\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\n\n\n# Data - Quarterly energy consumption by source with uncertainty\nnp.random.seed(42)\nquarters = pd.date_range(\"2020-01-01\", periods=20, freq=\"QE\")\n\n# Generate energy consumption data for 3 sources (in TWh)\n# Solar: growing trend with increasing uncertainty\nsolar_base = np.linspace(50, 150, 20) + np.random.randn(20) * 5\nsolar_uncertainty = np.linspace(10, 30, 20)\n\n# Wind: moderate growth with steady uncertainty\nwind_base = np.linspace(80, 130, 20) + np.random.randn(20) * 8\nwind_uncertainty = np.ones(20) * 20\n\n# Hydro: stable with low uncertainty\nhydro_base = np.linspace(120, 125, 20) + np.random.randn(20) * 3\nhydro_uncertainty = np.ones(20) * 8\n\n# Create DataFrame with stacked values and confidence bands\ndf = pd.DataFrame({\"date\": quarters})\n\n# For stacked areas, we need cumulative values\n# Stack order: Hydro (bottom) -> Wind (middle) -> Solar (top)\ndf[\"hydro\"] = hydro_base\ndf[\"hydro_lower\"] = hydro_base - hydro_uncertainty\ndf[\"hydro_upper\"] = hydro_base + hydro_uncertainty\n\ndf[\"wind_base\"] = wind_base\ndf[\"wind\"] = df[\"hydro\"] + wind_base\ndf[\"wind_lower\"] = df[\"hydro_lower\"] + (wind_base - wind_uncertainty)\ndf[\"wind_upper\"] = df[\"hydro_upper\"] + (wind_base + wind_uncertainty)\n\ndf[\"solar_base\"] = solar_base\ndf[\"solar\"] = df[\"wind\"] + solar_base\ndf[\"solar_lower\"] = df[\"wind_lower\"] + (solar_base - solar_uncertainty)\ndf[\"solar_upper\"] = df[\"wind_upper\"] + (solar_base + solar_uncertainty)\n\n# Define colors (Python Blue primary, then complementary)\ncolors = {\"Hydro\": \"#306998\", \"Wind\": \"#4A90D9\", \"Solar\": \"#FFD43B\"}\n\n# Create long-format data for legend\nlegend_df = pd.DataFrame(\n    {\n        \"date\": list(quarters) * 3,\n        \"source\": [\"Hydro\"] * 20 + [\"Wind\"] * 20 + [\"Solar\"] * 20,\n        \"y\": list(df[\"hydro\"]) + list(df[\"wind\"]) + list(df[\"solar\"]),\n        \"y0\": [0] * 20 + list(df[\"hydro\"]) + list(df[\"wind\"]),\n    }\n)\n\n# Create base chart\nbase = alt.Chart(df).encode(x=alt.X(\"date:T\", title=\"Quarter\", axis=alt.Axis(format=\"%Y-Q%q\", labelFontSize=16)))\n\n# Hydro confidence band (bottom layer)\nhydro_band = base.mark_area(opacity=0.25, color=colors[\"Hydro\"]).encode(\n    y=alt.Y(\"hydro_lower:Q\", title=\"Energy Consumption (TWh)\", axis=alt.Axis(titleFontSize=20, labelFontSize=16)),\n    y2=alt.Y2(\"hydro_upper:Q\"),\n)\n\n# Wind confidence band (middle layer)\nwind_band = base.mark_area(opacity=0.25, color=colors[\"Wind\"]).encode(\n    y=alt.Y(\"wind_lower:Q\"), y2=alt.Y2(\"wind_upper:Q\")\n)\n\n# Solar confidence band (top layer)\nsolar_band = base.mark_area(opacity=0.25, color=colors[\"Solar\"]).encode(\n    y=alt.Y(\"solar_lower:Q\"), y2=alt.Y2(\"solar_upper:Q\")\n)\n\n# Create stacked areas with legend using long-format data\nstacked_areas = (\n    alt.Chart(legend_df)\n    .mark_area(opacity=0.75)\n    .encode(\n        x=alt.X(\"date:T\", title=\"Quarter\", axis=alt.Axis(format=\"%Y-Q%q\", labelFontSize=16)),\n        y=alt.Y(\"y0:Q\", title=\"Energy Consumption (TWh)\"),\n        y2=alt.Y2(\"y:Q\"),\n        color=alt.Color(\n            \"source:N\",\n            scale=alt.Scale(\n                domain=[\"Hydro\", \"Wind\", \"Solar\"], range=[colors[\"Hydro\"], colors[\"Wind\"], colors[\"Solar\"]]\n            ),\n            legend=alt.Legend(title=\"Energy Source\", titleFontSize=18, labelFontSize=16, symbolSize=300),\n        ),\n        order=alt.Order(\"source:N\", sort=\"ascending\"),\n    )\n)\n\n# Combine bands and stacked areas\nchart = (\n    alt.layer(hydro_band, wind_band, solar_band, stacked_areas)\n    .properties(\n        width=1400,\n        height=800,\n        title=alt.Title(\n            \"area-stacked-confidence · altair · pyplots.ai\",\n            fontSize=28,\n            subtitle=\"Renewable Energy Consumption Forecast with 90% Confidence Bands\",\n            subtitleFontSize=18,\n        ),\n    )\n    .configure_axis(titleFontSize=20, labelFontSize=16)\n    .configure_view(strokeWidth=0)\n    .configure_legend(titleFontSize=18, labelFontSize=16)\n)\n\n# Save outputs\nchart.save(\"plot.png\", scale_factor=3.0)\nchart.save(\"plot.html\")\n"}