{"spec_id":"area-stacked-confidence","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\narea-stacked-confidence: Stacked Area Chart with Confidence Bands\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 94/100 | Updated: 2026-05-18\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nimport plotly.graph_objects as go\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\"\nGRID = \"rgba(26, 26, 23, 0.10)\" if THEME == \"light\" else \"rgba(240, 239, 232, 0.10)\"\n\n# Okabe-Ito palette (positions 1-3 for three series)\nHYDRO_COLOR = \"#009E73\"  # Okabe-Ito position 1 (brand green)\nWIND_COLOR = \"#C475FD\"  # Okabe-Ito position 2 (vermillion)\nSOLAR_COLOR = \"#4467A3\"  # Okabe-Ito position 3 (blue)\n\n# Data - Quarterly energy consumption forecast by source with uncertainty bands\nnp.random.seed(42)\nquarters = [d.strftime(\"%Y-%m-%d\") for d in pd.date_range(\"2020-01-01\", periods=20, freq=\"QE\")]\n\n# Base values for energy consumption (in TWh)\nhydro_base = np.linspace(100, 110, 20) + np.random.randn(20) * 3\nwind_base = np.linspace(80, 150, 20) + np.random.randn(20) * 8\nsolar_base = np.linspace(50, 120, 20) + np.random.randn(20) * 5\n\n# Uncertainty increases over time (forecast uncertainty)\nuncertainty_growth = np.linspace(1, 2.5, 20)\nhydro_lower = hydro_base - 8 * uncertainty_growth\nhydro_upper = hydro_base + 8 * uncertainty_growth\nwind_lower = wind_base - 15 * uncertainty_growth\nwind_upper = wind_base + 15 * uncertainty_growth\nsolar_lower = solar_base - 10 * uncertainty_growth\nsolar_upper = solar_base + 10 * uncertainty_growth\n\n# Calculate stacked positions for central values\nhydro_stack = hydro_base\nwind_stack = hydro_base + wind_base\nsolar_stack = hydro_base + wind_base + solar_base\n\n# Calculate stacked positions for confidence bands\nhydro_lower_stack = hydro_lower\nhydro_upper_stack = hydro_upper\n\nwind_lower_stack = hydro_lower + wind_lower\nwind_upper_stack = hydro_upper + wind_upper\n\nsolar_lower_stack = hydro_lower + wind_lower + solar_lower\nsolar_upper_stack = hydro_upper + wind_upper + solar_upper\n\n# Create figure\nfig = go.Figure()\n\n# Hydro confidence band (bottom layer)\nfig.add_trace(\n    go.Scatter(\n        x=quarters + quarters[::-1],\n        y=list(hydro_upper_stack) + list(hydro_lower_stack[::-1]),\n        fill=\"toself\",\n        fillcolor=\"rgba(0, 158, 115, 0.25)\",\n        line=dict(color=\"rgba(255, 255, 255, 0)\"),\n        showlegend=False,\n        name=\"Hydro Band\",\n        hoverinfo=\"skip\",\n    )\n)\n\n# Hydro central area\nfig.add_trace(\n    go.Scatter(\n        x=quarters,\n        y=hydro_stack,\n        mode=\"lines\",\n        line=dict(color=HYDRO_COLOR, width=3),\n        name=\"Hydro\",\n        fill=\"tozeroy\",\n        fillcolor=\"rgba(0, 158, 115, 0.6)\",\n    )\n)\n\n# Wind confidence band (middle layer)\nfig.add_trace(\n    go.Scatter(\n        x=quarters + quarters[::-1],\n        y=list(wind_upper_stack) + list(wind_lower_stack[::-1]),\n        fill=\"toself\",\n        fillcolor=\"rgba(196, 117, 253, 0.25)\",\n        line=dict(color=\"rgba(255, 255, 255, 0)\"),\n        showlegend=False,\n        name=\"Wind Band\",\n        hoverinfo=\"skip\",\n    )\n)\n\n# Wind central area\nfig.add_trace(\n    go.Scatter(\n        x=quarters,\n        y=wind_stack,\n        mode=\"lines\",\n        line=dict(color=WIND_COLOR, width=3),\n        name=\"Wind\",\n        fill=\"tonexty\",\n        fillcolor=\"rgba(196, 117, 253, 0.6)\",\n    )\n)\n\n# Solar confidence band (top layer)\nfig.add_trace(\n    go.Scatter(\n        x=quarters + quarters[::-1],\n        y=list(solar_upper_stack) + list(solar_lower_stack[::-1]),\n        fill=\"toself\",\n        fillcolor=\"rgba(68, 103, 163, 0.25)\",\n        line=dict(color=\"rgba(255, 255, 255, 0)\"),\n        showlegend=False,\n        name=\"Solar Band\",\n        hoverinfo=\"skip\",\n    )\n)\n\n# Solar central area\nfig.add_trace(\n    go.Scatter(\n        x=quarters,\n        y=solar_stack,\n        mode=\"lines\",\n        line=dict(color=SOLAR_COLOR, width=3),\n        name=\"Solar\",\n        fill=\"tonexty\",\n        fillcolor=\"rgba(68, 103, 163, 0.6)\",\n    )\n)\n\n# Layout\nfig.update_layout(\n    title=dict(\n        text=\"area-stacked-confidence · Python · plotly · anyplot.ai\",\n        font=dict(size=28, color=INK),\n        x=0.5,\n        xanchor=\"center\",\n    ),\n    xaxis=dict(\n        title=dict(text=\"Quarter\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        showgrid=True,\n        gridwidth=1,\n        gridcolor=GRID,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    yaxis=dict(\n        title=dict(text=\"Energy Consumption (TWh)\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        showgrid=True,\n        gridwidth=1,\n        gridcolor=GRID,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    legend=dict(\n        font=dict(size=18, color=INK_SOFT), x=0.02, y=0.98, bgcolor=ELEVATED_BG, bordercolor=INK_SOFT, borderwidth=1\n    ),\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    hovermode=\"x unified\",\n    margin=dict(l=80, r=40, t=80, b=60),\n)\n\n# Save\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}