Skip to content

Commit 965aa31

Browse files
feat(altair): implement histogram-stacked (#2618)
## Implementation: `histogram-stacked` - altair Implements the **altair** version of `histogram-stacked`. **File:** `plots/histogram-stacked/implementations/altair.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20594559490)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 4c097fc commit 965aa31

2 files changed

Lines changed: 102 additions & 0 deletions

File tree

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
""" pyplots.ai
2+
histogram-stacked: Stacked Histogram
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 - Test scores from three different study methods
13+
np.random.seed(42)
14+
15+
# Generate realistic test score distributions for three study methods
16+
method_a = np.random.normal(loc=72, scale=10, size=150) # Traditional study
17+
method_b = np.random.normal(loc=78, scale=8, size=120) # Active recall
18+
method_c = np.random.normal(loc=68, scale=12, size=100) # Passive reading
19+
20+
# Clip to valid score range (0-100)
21+
method_a = np.clip(method_a, 0, 100)
22+
method_b = np.clip(method_b, 0, 100)
23+
method_c = np.clip(method_c, 0, 100)
24+
25+
# Create DataFrame
26+
df = pd.DataFrame(
27+
{
28+
"Score": np.concatenate([method_a, method_b, method_c]),
29+
"Study Method": (
30+
["Traditional Study"] * len(method_a)
31+
+ ["Active Recall"] * len(method_b)
32+
+ ["Passive Reading"] * len(method_c)
33+
),
34+
}
35+
)
36+
37+
# Create stacked histogram using binned bar chart
38+
chart = (
39+
alt.Chart(df)
40+
.mark_bar(opacity=0.85, stroke="white", strokeWidth=0.5)
41+
.encode(
42+
x=alt.X(
43+
"Score:Q",
44+
bin=alt.Bin(maxbins=20),
45+
title="Test Score (points)",
46+
axis=alt.Axis(labelFontSize=18, titleFontSize=22),
47+
),
48+
y=alt.Y(
49+
"count():Q", title="Number of Students", stack="zero", axis=alt.Axis(labelFontSize=18, titleFontSize=22)
50+
),
51+
color=alt.Color(
52+
"Study Method:N",
53+
scale=alt.Scale(
54+
domain=["Traditional Study", "Active Recall", "Passive Reading"],
55+
range=["#306998", "#FFD43B", "#E67E22"],
56+
),
57+
legend=alt.Legend(title="Study Method", titleFontSize=18, labelFontSize=16, orient="right"),
58+
),
59+
order=alt.Order("Study Method:N", sort="ascending"),
60+
)
61+
.properties(
62+
width=1600, height=900, title=alt.Title("histogram-stacked · altair · pyplots.ai", fontSize=28, anchor="middle")
63+
)
64+
.configure_axis(grid=True, gridOpacity=0.3, gridDash=[2, 2])
65+
.configure_view(strokeWidth=0)
66+
)
67+
68+
# Save as PNG (scale_factor=3 gives 4800x2700)
69+
chart.save("plot.png", scale_factor=3.0)
70+
71+
# Save interactive HTML version
72+
chart.save("plot.html")
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
library: altair
2+
specification_id: histogram-stacked
3+
created: '2025-12-30T10:38:08Z'
4+
updated: '2025-12-30T10:45:48Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20594559490
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/histogram-stacked/altair/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/histogram-stacked/altair/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/histogram-stacked/altair/plot.html
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent declarative encoding with proper use of Altair grammar (alt.X with bin,
17+
alt.Y with stack="zero", alt.Color with custom scale)
18+
- Clean, readable code following KISS principles with good data generation
19+
- Proper font sizing throughout (title 28pt, axis titles 22pt, labels 18pt, legend
20+
16-18pt)
21+
- Good color palette choice (blue, yellow, orange) that avoids colorblind issues
22+
- White stroke between bar segments (strokeWidth=0.5) enhances visual separation
23+
- Appropriate use of scale_factor=3.0 for high-resolution output
24+
- Both PNG and HTML outputs generated for static and interactive viewing
25+
weaknesses:
26+
- Legend styling could be more polished (title and label fonts could be slightly
27+
larger for better visual hierarchy)
28+
- Could add tooltips for interactive exploration showing exact counts per bin
29+
- The order parameter could be more intentionally designed to show a specific visual
30+
story (e.g., ordering by mean score)

0 commit comments

Comments
 (0)