Skip to content

Commit a3b2231

Browse files
update(pie-basic): altair — comprehensive quality review (#4220)
## Summary Updated **altair** implementation for **pie-basic**. **Changes:** Comprehensive review improving code quality, data choice, visual design, spec compliance, and library feature usage. ## Test Plan - [x] Preview images uploaded to GCS staging - [x] Implementation file passes ruff format/check - [x] Metadata YAML updated with current versions - [ ] Automated review triggered --- Generated with [Claude Code](https://claude.com/claude-code) `/update` command --------- 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 afd3c28 commit a3b2231

2 files changed

Lines changed: 212 additions & 125 deletions

File tree

plots/pie-basic/implementations/altair.py

Lines changed: 82 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,113 @@
11
""" pyplots.ai
22
pie-basic: Basic Pie Chart
3-
Library: altair 6.0.0 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: altair 6.0.0 | Python 3.14.0
4+
Quality: 90/100 | Created: 2025-12-23
55
"""
66

77
import altair as alt
88
import pandas as pd
99

1010

11-
# Data - Budget allocation by department
11+
# Data - Cloud infrastructure market share
1212
data = pd.DataFrame(
13-
{"category": ["Engineering", "Marketing", "Operations", "Sales", "HR", "R&D"], "value": [35, 20, 18, 15, 7, 5]}
13+
{"category": ["AWS", "Azure", "Google Cloud", "Alibaba", "Oracle", "Others"], "value": [31, 24, 11, 4, 3, 27]}
1414
)
1515

16-
# Calculate percentages for labels
17-
data["percentage"] = data["value"] / data["value"].sum() * 100
18-
data["label"] = data["percentage"].apply(lambda x: f"{x:.1f}%")
16+
total = data["value"].sum()
17+
data["percentage"] = data["value"] / total * 100
18+
data["label"] = data["percentage"].apply(lambda x: f"{x:.0f}%")
19+
data["order"] = range(len(data))
1920

20-
# Color palette - Python Blue first, then colorblind-safe colors
21-
colors = ["#306998", "#FFD43B", "#4ECDC4", "#FF6B6B", "#95E1D3", "#F38181"]
21+
# Color palette - Python Blue first, cohesive colorblind-safe
22+
colors = ["#306998", "#FFD43B", "#4ECDC4", "#FF6B6B", "#95E1D3", "#A8A8A8"]
23+
domain = data["category"].tolist()
2224

23-
# Base chart
25+
color_scale = alt.Scale(domain=domain, range=colors)
26+
27+
# Shared base with encodings
2428
base = alt.Chart(data).encode(
2529
theta=alt.Theta("value:Q", stack=True),
30+
order=alt.Order("order:O"),
2631
color=alt.Color(
2732
"category:N",
28-
scale=alt.Scale(range=colors),
29-
legend=alt.Legend(title="Department", titleFontSize=20, labelFontSize=18, symbolSize=300, orient="right"),
33+
scale=color_scale,
34+
legend=alt.Legend(
35+
title="Provider",
36+
titleFontSize=20,
37+
labelFontSize=18,
38+
symbolSize=300,
39+
orient="bottom",
40+
direction="horizontal",
41+
columns=6,
42+
titleAnchor="middle",
43+
),
3044
),
31-
tooltip=[
32-
alt.Tooltip("category:N", title="Department"),
33-
alt.Tooltip("value:Q", title="Budget Share"),
34-
alt.Tooltip("label:N", title="Percentage"),
35-
],
3645
)
3746

38-
# Pie slices with white stroke for separation
39-
pie = base.mark_arc(outerRadius=320, innerRadius=0, stroke="#ffffff", strokeWidth=2)
47+
# Main pie slices (non-AWS)
48+
pie = (
49+
base.transform_filter(alt.datum.category != "AWS")
50+
.mark_arc(outerRadius=370, innerRadius=0, stroke="#ffffff", strokeWidth=2.5, padAngle=0.02, cornerRadius=3)
51+
.encode(tooltip=[alt.Tooltip("category:N", title="Provider"), alt.Tooltip("value:Q", title="Market Share (%)")])
52+
)
53+
54+
# Exploded AWS slice — offset via radiusOffset for visible displacement
55+
exploded_aws = (
56+
base.transform_filter(alt.datum.category == "AWS")
57+
.mark_arc(
58+
outerRadius=370, innerRadius=0, radiusOffset=22, stroke="#ffffff", strokeWidth=3, padAngle=0.04, cornerRadius=3
59+
)
60+
.encode(tooltip=[alt.Tooltip("category:N", title="Provider"), alt.Tooltip("value:Q", title="Market Share (%)")])
61+
)
62+
63+
# Percentage labels outside slices — larger radius for better separation
64+
text_main = (
65+
base.transform_filter(alt.datum.category != "AWS")
66+
.mark_text(radius=420, fontSize=21, fontWeight="bold")
67+
.encode(text="label:N")
68+
)
69+
70+
# AWS label with matching offset
71+
text_aws = (
72+
base.transform_filter(alt.datum.category == "AWS")
73+
.mark_text(radius=420, radiusOffset=22, fontSize=21, fontWeight="bold")
74+
.encode(text="label:N")
75+
)
4076

41-
# Percentage labels on slices
42-
text = base.mark_text(radius=380, fontSize=20, fontWeight="bold").encode(text="label:N")
77+
# Annotation: AWS callout as market leader
78+
aws_note = (
79+
alt.Chart(pd.DataFrame({"text": ["AWS leads at 31% — largest single provider"]}))
80+
.mark_text(fontSize=16, fontStyle="italic", color="#306998", align="left")
81+
.encode(x=alt.value(720), y=alt.value(100), text="text:N")
82+
)
83+
84+
# Annotation: "Others" insight (positioned below chart, left-aligned)
85+
others_note = (
86+
alt.Chart(pd.DataFrame({"text": ['"Others" at 27% collectively outpace all but AWS']}))
87+
.mark_text(fontSize=16, fontStyle="italic", color="#777777", align="left")
88+
.encode(x=alt.value(100), y=alt.value(980), text="text:N")
89+
)
4390

44-
# Combine pie and labels
91+
# Combine all layers — compact layout with legend closer to chart
4592
chart = (
46-
alt.layer(pie, text)
93+
alt.layer(pie, exploded_aws, text_main, text_aws, aws_note, others_note)
4794
.properties(
48-
width=1200, height=1200, title=alt.Title(text="pie-basic · altair · pyplots.ai", fontSize=28, anchor="middle")
95+
width=1200,
96+
height=1000,
97+
title=alt.Title(
98+
text="pie-basic · altair · pyplots.ai",
99+
subtitle="Global Cloud Infrastructure Market Share",
100+
fontSize=28,
101+
subtitleFontSize=20,
102+
subtitleColor="#666666",
103+
anchor="middle",
104+
),
49105
)
50106
.configure_view(strokeWidth=0)
107+
.configure_legend(padding=20, offset=10)
51108
)
52109

53-
# Save as PNG (scale_factor=3 gives us 3600x3600 for square format)
110+
# Save as PNG (scale_factor=3 → ~3300x3150 square-ish format)
54111
chart.save("plot.png", scale_factor=3.0)
55112

56113
# Save interactive HTML

0 commit comments

Comments
 (0)