Skip to content

Commit 48fc694

Browse files
feat(altair): implement area-stacked-percent (#2676)
## Implementation: `area-stacked-percent` - altair Implements the **altair** version of `area-stacked-percent`. **File:** `plots/area-stacked-percent/implementations/altair.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20595338920)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 7db0c40 commit 48fc694

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
""" pyplots.ai
2+
area-stacked-percent: 100% Stacked Area Chart
3+
Library: altair 6.0.0 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-30
5+
"""
6+
7+
import altair as alt
8+
import numpy as np
9+
import pandas as pd
10+
11+
12+
# Data - Energy source mix evolution (percentage of total)
13+
np.random.seed(42)
14+
years = list(range(2015, 2025))
15+
16+
# Start with base percentages and evolve them (showing transition from fossil to renewables)
17+
coal = [45, 42, 39, 35, 32, 28, 25, 22, 19, 16]
18+
natural_gas = [25, 26, 27, 28, 29, 30, 31, 31, 30, 28]
19+
nuclear = [12, 12, 12, 12, 12, 12, 12, 12, 12, 12]
20+
renewables = [18, 20, 22, 25, 27, 30, 32, 35, 39, 44]
21+
22+
# Create DataFrame in long format for Altair
23+
data = []
24+
for i, year in enumerate(years):
25+
data.append({"Year": year, "Source": "Coal", "Percentage": coal[i]})
26+
data.append({"Year": year, "Source": "Natural Gas", "Percentage": natural_gas[i]})
27+
data.append({"Year": year, "Source": "Nuclear", "Percentage": nuclear[i]})
28+
data.append({"Year": year, "Source": "Renewables", "Percentage": renewables[i]})
29+
30+
df = pd.DataFrame(data)
31+
32+
# Define category order for stacking (bottom to top) using numeric order
33+
source_order = ["Coal", "Natural Gas", "Nuclear", "Renewables"]
34+
stack_order = {"Coal": 1, "Natural Gas": 2, "Nuclear": 3, "Renewables": 4}
35+
df["StackOrder"] = df["Source"].map(stack_order)
36+
37+
# Color palette using Python colors and complementary
38+
colors = ["#306998", "#FFD43B", "#7B68EE", "#2E8B57"]
39+
40+
# Plot - 100% Stacked Area Chart
41+
chart = (
42+
alt.Chart(df)
43+
.mark_area(opacity=0.85, line=alt.MarkConfig(strokeWidth=2))
44+
.encode(
45+
x=alt.X("Year:O", title="Year", axis=alt.Axis(labelFontSize=18, titleFontSize=22, labelAngle=0)),
46+
y=alt.Y(
47+
"Percentage:Q",
48+
title="Share of Energy Mix (%)",
49+
stack="normalize",
50+
axis=alt.Axis(labelFontSize=18, titleFontSize=22, format=".0%"),
51+
),
52+
color=alt.Color(
53+
"Source:N",
54+
scale=alt.Scale(domain=source_order, range=colors),
55+
legend=alt.Legend(
56+
title="Energy Source",
57+
titleFontSize=20,
58+
labelFontSize=18,
59+
orient="right",
60+
symbolSize=300,
61+
symbolStrokeWidth=0,
62+
),
63+
),
64+
order=alt.Order("StackOrder:Q", sort="ascending"),
65+
tooltip=[
66+
alt.Tooltip("Year:O", title="Year"),
67+
alt.Tooltip("Source:N", title="Source"),
68+
alt.Tooltip("Percentage:Q", title="Share", format=".1f"),
69+
],
70+
)
71+
.properties(
72+
width=1400,
73+
height=800,
74+
title=alt.Title(text="area-stacked-percent · altair · pyplots.ai", fontSize=28, anchor="middle"),
75+
)
76+
.configure_axis(grid=True, gridOpacity=0.3, gridDash=[4, 4])
77+
.configure_view(strokeWidth=0)
78+
)
79+
80+
# Save
81+
chart.save("plot.png", scale_factor=3.0)
82+
chart.interactive().save("plot.html")
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
library: altair
2+
specification_id: area-stacked-percent
3+
created: '2025-12-30T11:23:32Z'
4+
updated: '2025-12-30T11:36:09Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20595338920
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 6.0.0
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/area-stacked-percent/altair/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/area-stacked-percent/altair/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/area-stacked-percent/altair/plot.html
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent use of Altair's declarative grammar with stack="normalize" for proper
17+
100% stacking
18+
- Clear, compelling real-world narrative (energy transition) that perfectly demonstrates
19+
the spec
20+
- Clean code structure following KISS principles with well-organized long-format
21+
data
22+
- Good typography sizing making all text highly readable
23+
- Appropriate use of tooltips and interactive HTML export
24+
- Proper stacking order using explicit order encoding
25+
weaknesses:
26+
- Legend positioned outside creates slight whitespace imbalance; consider moving
27+
inside plot area
28+
- Nuclear data staying perfectly flat at 12% for all 10 years feels artificially
29+
constant

0 commit comments

Comments
 (0)