|
| 1 | +""" pyplots.ai |
| 2 | +area-stacked-percent: 100% Stacked Area Chart |
| 3 | +Library: plotly 6.5.0 | Python 3.13.11 |
| 4 | +Quality: 92/100 | Created: 2025-12-30 |
| 5 | +""" |
| 6 | + |
| 7 | +import numpy as np |
| 8 | +import plotly.graph_objects as go |
| 9 | + |
| 10 | + |
| 11 | +# Data - Energy source market share over time |
| 12 | +np.random.seed(42) |
| 13 | +years = list(range(2015, 2025)) |
| 14 | + |
| 15 | +# Simulate energy source percentages that evolve over time |
| 16 | +# Solar grows, Coal declines, Natural Gas stable, Wind grows |
| 17 | +coal_base = np.linspace(40, 22, len(years)) + np.random.randn(len(years)) * 2 |
| 18 | +gas_base = np.linspace(30, 32, len(years)) + np.random.randn(len(years)) * 1 |
| 19 | +wind_base = np.linspace(12, 20, len(years)) + np.random.randn(len(years)) * 1 |
| 20 | +solar_base = np.linspace(8, 18, len(years)) + np.random.randn(len(years)) * 1 |
| 21 | +hydro_base = np.linspace(10, 8, len(years)) + np.random.randn(len(years)) * 0.5 |
| 22 | + |
| 23 | +# Ensure no negative values |
| 24 | +coal_base = np.clip(coal_base, 5, 50) |
| 25 | +gas_base = np.clip(gas_base, 20, 40) |
| 26 | +wind_base = np.clip(wind_base, 5, 25) |
| 27 | +solar_base = np.clip(solar_base, 3, 25) |
| 28 | +hydro_base = np.clip(hydro_base, 5, 15) |
| 29 | + |
| 30 | +# Normalize to 100% |
| 31 | +totals = coal_base + gas_base + wind_base + solar_base + hydro_base |
| 32 | +coal = (coal_base / totals) * 100 |
| 33 | +gas = (gas_base / totals) * 100 |
| 34 | +wind = (wind_base / totals) * 100 |
| 35 | +solar = (solar_base / totals) * 100 |
| 36 | +hydro = (hydro_base / totals) * 100 |
| 37 | + |
| 38 | +# Colors - Python Blue, Yellow, and additional colorblind-safe colors |
| 39 | +colors = ["#306998", "#FFD43B", "#4DAF4A", "#E7298A", "#66A61E"] |
| 40 | + |
| 41 | +# Create figure |
| 42 | +fig = go.Figure() |
| 43 | + |
| 44 | +# Add stacked areas (using stackgroup for 100% stacking) |
| 45 | +categories = ["Coal", "Natural Gas", "Wind", "Solar", "Hydro"] |
| 46 | +values = [coal, gas, wind, solar, hydro] |
| 47 | + |
| 48 | +for i, (cat, val) in enumerate(zip(categories, values)): |
| 49 | + fig.add_trace( |
| 50 | + go.Scatter( |
| 51 | + x=years, |
| 52 | + y=val, |
| 53 | + name=cat, |
| 54 | + mode="lines", |
| 55 | + line=dict(width=0.5, color=colors[i]), |
| 56 | + stackgroup="one", |
| 57 | + groupnorm="percent", |
| 58 | + fillcolor=colors[i], |
| 59 | + hovertemplate="%{y:.1f}%<extra>" + cat + "</extra>", |
| 60 | + ) |
| 61 | + ) |
| 62 | + |
| 63 | +# Update layout |
| 64 | +fig.update_layout( |
| 65 | + title=dict(text="area-stacked-percent · plotly · pyplots.ai", font=dict(size=28), x=0.5, xanchor="center"), |
| 66 | + xaxis=dict( |
| 67 | + title=dict(text="Year", font=dict(size=22)), |
| 68 | + tickfont=dict(size=18), |
| 69 | + dtick=1, |
| 70 | + showgrid=True, |
| 71 | + gridwidth=1, |
| 72 | + gridcolor="rgba(0,0,0,0.1)", |
| 73 | + ), |
| 74 | + yaxis=dict( |
| 75 | + title=dict(text="Market Share (%)", font=dict(size=22)), |
| 76 | + tickfont=dict(size=18), |
| 77 | + ticksuffix="%", |
| 78 | + range=[0, 100], |
| 79 | + showgrid=True, |
| 80 | + gridwidth=1, |
| 81 | + gridcolor="rgba(0,0,0,0.1)", |
| 82 | + ), |
| 83 | + template="plotly_white", |
| 84 | + legend=dict(font=dict(size=18), orientation="h", yanchor="bottom", y=1.02, xanchor="center", x=0.5), |
| 85 | + margin=dict(l=80, r=40, t=120, b=60), |
| 86 | + hovermode="x unified", |
| 87 | +) |
| 88 | + |
| 89 | +# Save as PNG and HTML |
| 90 | +fig.write_image("plot.png", width=1600, height=900, scale=3) |
| 91 | +fig.write_html("plot.html", include_plotlyjs="cdn") |
0 commit comments