Skip to content

Commit 54028d2

Browse files
update(bar-basic): altair — comprehensive quality review (#4212)
## Summary Updated **altair** implementation for **bar-basic**. ### Changes - Added value labels above bars via `mark_text()` layer composition - Grid changed to Y-axis only - Chart dimensions adjusted to 1600x900 (exact 4800x2700 at 3x) ## 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 03ded89 commit 54028d2

File tree

2 files changed

+188
-130
lines changed

2 files changed

+188
-130
lines changed

plots/bar-basic/implementations/altair.py

Lines changed: 44 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,74 @@
11
""" pyplots.ai
22
bar-basic: Basic Bar Chart
3-
Library: altair 6.0.0 | Python 3.13.11
4-
Quality: 93/100 | Created: 2025-12-23
3+
Library: altair 6.0.0 | Python 3.14
4+
Quality: 92/100 | Created: 2025-12-23
55
"""
66

77
import altair as alt
88
import pandas as pd
99

1010

1111
# Data - Product sales by category (realistic retail scenario)
12+
# Includes close-valued pairs (Clothing/Home & Garden, Toys/Food) to showcase comparison
1213
data = pd.DataFrame(
1314
{
1415
"category": ["Electronics", "Clothing", "Home & Garden", "Sports", "Books", "Toys", "Food"],
15-
"value": [45200, 32100, 28400, 21800, 18500, 15200, 12300],
16+
"value": [45200, 31500, 29800, 21800, 18500, 14200, 13100],
1617
}
1718
)
1819

19-
# Chart
20-
chart = (
20+
# Highlight the top-performing category
21+
data["is_top"] = data["value"] == data["value"].max()
22+
23+
# Sort order by descending value
24+
sort_order = data.sort_values("value", ascending=False)["category"].tolist()
25+
26+
# Chart - bars with conditional color to highlight leader
27+
bars = (
2128
alt.Chart(data)
22-
.mark_bar(color="#306998", cornerRadiusTopLeft=4, cornerRadiusTopRight=4)
29+
.mark_bar(cornerRadiusTopLeft=4, cornerRadiusTopRight=4)
2330
.encode(
2431
x=alt.X(
2532
"category:N",
2633
title="Product Category",
27-
sort="-y",
34+
sort=sort_order,
2835
axis=alt.Axis(labelAngle=-45, labelFontSize=18, titleFontSize=22),
2936
),
30-
y=alt.Y("value:Q", title="Sales ($)", axis=alt.Axis(labelFontSize=18, titleFontSize=22, format="$,.0f")),
37+
y=alt.Y(
38+
"value:Q",
39+
title="Sales ($)",
40+
scale=alt.Scale(domain=[0, 50000]),
41+
axis=alt.Axis(
42+
labelFontSize=18, titleFontSize=22, format="$,.0f", values=[0, 10000, 20000, 30000, 40000, 50000]
43+
),
44+
),
45+
color=alt.condition(alt.datum.is_top, alt.value("#FFD43B"), alt.value("#306998")),
3146
tooltip=[alt.Tooltip("category:N", title="Category"), alt.Tooltip("value:Q", title="Sales", format="$,.0f")],
3247
)
33-
.properties(width=1500, height=800, title=alt.Title(text="bar-basic · altair · pyplots.ai", fontSize=28))
48+
)
49+
50+
# Value labels above bars
51+
labels = bars.mark_text(align="center", baseline="bottom", dy=-8, fontSize=16, color="#333333").encode(
52+
text=alt.Text("value:Q", format="$,.0f"), color=alt.value("#333333")
53+
)
54+
55+
# Annotation highlighting top performer
56+
annotation = (
57+
alt.Chart(pd.DataFrame({"category": ["Electronics"], "value": [45200], "label": ["Top seller — $45.2k"]}))
58+
.mark_text(align="center", baseline="bottom", dy=-28, fontSize=18, fontWeight="bold", color="#b8860b")
59+
.encode(x=alt.X("category:N", sort=sort_order), y=alt.Y("value:Q"), text=alt.Text("label:N"))
60+
)
61+
62+
# Combine bars + labels + annotation
63+
chart = (
64+
(bars + labels + annotation)
65+
.properties(width=1600, height=900, title=alt.Title(text="bar-basic · altair · pyplots.ai", fontSize=28))
3466
.configure_view(strokeWidth=0)
35-
.configure_axis(grid=True, gridOpacity=0.3, gridDash=[4, 4])
67+
.configure_axis(grid=False)
68+
.configure_axisY(grid=True, gridOpacity=0.15, gridDash=[4, 4])
3669
)
3770

38-
# Save as PNG (scale_factor=3 gives 4500x2400, close to target 4800x2700)
71+
# Save as PNG (scale_factor=3 gives 4800x2700 at 1600x900)
3972
chart.save("plot.png", scale_factor=3.0)
4073

4174
# Save interactive HTML

0 commit comments

Comments
 (0)