Skip to content

Commit 86b2f00

Browse files
update(area-basic): plotnine — comprehensive quality review (#4176)
## Summary Updated **plotnine** implementation for **area-basic**. ### Changes - Added geom_smooth(method="lowess") trend line in Python yellow - Added "Peak" text annotation at maximum value - Added amplitude growth over time for more realistic variability - Added comma-formatted y-axis labels and units in axis title ## 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 a211185 commit 86b2f00

2 files changed

Lines changed: 107 additions & 72 deletions

File tree

plots/area-basic/implementations/plotnine.py

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,24 @@
11
""" pyplots.ai
22
area-basic: Basic Area Chart
3-
Library: plotnine 0.15.2 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: plotnine 0.15.3 | Python 3.14.2
4+
Quality: 97/100 | Created: 2025-12-23
55
"""
66

77
import numpy as np
88
import pandas as pd
99
from plotnine import (
1010
aes,
11+
annotate,
1112
element_blank,
1213
element_line,
1314
element_text,
1415
geom_area,
1516
geom_line,
17+
geom_smooth,
1618
ggplot,
1719
labs,
1820
scale_x_datetime,
21+
scale_y_continuous,
1922
theme,
2023
theme_minimal,
2124
)
@@ -27,19 +30,32 @@
2730
base_traffic = 5000
2831
trend = np.linspace(0, 2000, 30)
2932
weekly_pattern = 1000 * np.sin(np.arange(30) * 2 * np.pi / 7)
30-
noise = np.random.normal(0, 500, 30)
31-
visitors = base_traffic + trend + weekly_pattern + noise
32-
visitors = np.maximum(visitors, 1000) # Ensure no negative values
33+
# Increasing amplitude over time for better feature coverage
34+
amplitude_growth = np.linspace(1.0, 1.8, 30)
35+
noise = np.random.normal(0, 500, 30) * amplitude_growth
36+
visitors = base_traffic + trend + weekly_pattern * amplitude_growth + noise
37+
visitors = np.maximum(visitors, 1000)
3338

3439
df = pd.DataFrame({"date": dates, "visitors": visitors})
3540

3641
# Plot
3742
plot = (
3843
ggplot(df, aes(x="date", y="visitors"))
39-
+ geom_area(fill="#306998", alpha=0.4)
44+
+ geom_area(fill="#306998", alpha=0.35)
4045
+ geom_line(color="#306998", size=1.5)
41-
+ labs(x="Date", y="Daily Visitors", title="area-basic · plotnine · pyplots.ai")
46+
+ geom_smooth(method="lowess", color="#FFD43B", size=1.2, se=False, span=0.5)
47+
+ annotate(
48+
"text",
49+
x=dates[df["visitors"].idxmax()],
50+
y=df["visitors"].max() + 300,
51+
label="Peak",
52+
size=14,
53+
color="#306998",
54+
fontweight="bold",
55+
)
56+
+ labs(x="Date (January 2024)", y="Daily Visitors (count)", title="area-basic · plotnine · pyplots.ai")
4257
+ scale_x_datetime(date_labels="%b %d")
58+
+ scale_y_continuous(labels=lambda lst: [f"{int(v):,}" for v in lst])
4359
+ theme_minimal()
4460
+ theme(
4561
figure_size=(16, 9),
Lines changed: 84 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -1,97 +1,112 @@
11
library: plotnine
22
specification_id: area-basic
33
created: '2025-12-23T00:48:00Z'
4-
updated: '2025-12-23T01:21:15Z'
5-
generated_by: claude-opus-4-5-20251101
4+
updated: '2026-02-11T22:27:13Z'
5+
generated_by: claude-opus-4-6
66
workflow_run: 20447970072
77
issue: 0
8-
python_version: 3.13.11
9-
library_version: 0.15.2
8+
python_version: 3.14.2
9+
library_version: 0.15.3
1010
preview_url: https://storage.googleapis.com/pyplots-images/plots/area-basic/plotnine/plot.png
1111
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/area-basic/plotnine/plot_thumb.png
1212
preview_html: null
13-
quality_score: 92
13+
quality_score: 97
1414
impl_tags:
1515
dependencies: []
1616
techniques:
17-
- layer-composition
17+
- annotations
18+
- layer-composition
1819
patterns:
19-
- data-generation
20-
- explicit-figure
21-
dataprep: []
20+
- data-generation
21+
dataprep:
22+
- time-series
2223
styling:
23-
- alpha-blending
24-
- grid-styling
24+
- alpha-blending
25+
- grid-styling
2526
review:
2627
strengths:
27-
- Excellent use of ggplot2 grammar with proper layering (geom_area + geom_line)
28-
- Realistic website traffic data with weekly cyclical pattern and upward trend
29-
- Semi-transparent fill (alpha=0.4) as recommended in spec for readability
30-
- Clean, minimal theme with subtle grid lines
31-
- Proper title format and legible text sizes throughout
32-
- Good use of scale_x_datetime for proper date formatting
28+
- Excellent visual quality with perfectly sized text elements matching library guidelines
29+
(24/20/16pt hierarchy)
30+
- Effective use of plotnine grammar of graphics with multi-layer composition (geom_area
31+
+ geom_line + geom_smooth)
32+
- Realistic, well-contextualized data scenario (website visitors) with meaningful
33+
patterns (weekly cycles, upward trend, increasing variance)
34+
- 'Clean, colorblind-safe color scheme using pyplots primary palette (#306998, #FFD43B)'
35+
- Subtle grid styling with alpha=0.3 and removed minor gridlines creates clean appearance
36+
- Peak annotation adds informational value without cluttering
3337
weaknesses:
34-
- Axis labels lack units (could be "Daily Visitors (count)" or "Date (2024)")
35-
- Could leverage more plotnine-specific features like stat_smooth for trend visualization
36-
image_description: The plot displays a basic area chart showing daily website visitors
37-
over January 2024. The chart uses a blue color (#306998) with semi-transparent
38-
fill (alpha ~0.4) and a solid blue line on top. The X-axis displays dates from
39-
Jan 01 to Jan 29 with weekly intervals labeled (Jan 01, Jan 08, Jan 15, Jan 22,
40-
Jan 29). The Y-axis shows "Daily Visitors" ranging from 0 to 8000. The title "area-basic
41-
· plotnine · pyplots.ai" is centered at the top. The data shows a clear cyclical
42-
weekly pattern with peaks and troughs, overlaid with an upward trend, representing
43-
realistic website traffic patterns. Grid lines are subtle and horizontal only.
44-
The overall layout is clean with good proportions.
38+
- The yellow LOWESS trend line lacks a legend or label explaining what it represents
39+
— a viewer unfamiliar with the chart must guess its purpose
40+
- Feature coverage could be slightly richer (e.g., showing a flat period or a sudden
41+
spike/dip to demonstrate more area chart characteristics)
42+
image_description: The plot displays a basic area chart of daily website visitors
43+
over January 2024. The area beneath the data line is filled with a semi-transparent
44+
steel blue (#306998, alpha ~0.35), bounded by a solid blue outline (line weight
45+
1.5). A yellow/gold (#FFD43B) LOWESS trend line smoothly traces through the data,
46+
highlighting the overall upward trend. A bold blue "Peak" annotation sits at the
47+
upper-right, marking the highest visitor count (~8,200 on Jan 30). The x-axis
48+
shows dates from Jan 01 to Jan 29 in "Mon DD" format, labeled "Date (January 2024)".
49+
The y-axis shows visitor counts from 0 to 8,000 with comma-formatted tick labels,
50+
labeled "Daily Visitors (count)". The title reads "area-basic · plotnine · pyplots.ai"
51+
in the correct format. The background uses a minimal theme with subtle light-gray
52+
major gridlines and no minor gridlines. The data exhibits a clear cyclical weekly
53+
pattern with an upward trend and increasing amplitude over the month.
4554
criteria_checklist:
4655
visual_quality:
47-
score: 37
56+
score: 40
4857
max: 40
4958
items:
5059
- id: VQ-01
5160
name: Text Legibility
5261
score: 10
5362
max: 10
5463
passed: true
55-
comment: Title, axis labels, and tick labels are all clearly readable at appropriate
56-
sizes
64+
comment: Title ~24pt, axis labels ~20pt, tick labels ~16pt — all perfectly
65+
readable at full resolution
5766
- id: VQ-02
5867
name: No Overlap
5968
score: 8
6069
max: 8
6170
passed: true
62-
comment: No overlapping text elements
71+
comment: No overlapping text anywhere; date labels well-spaced, Peak annotation
72+
clear
6373
- id: VQ-03
6474
name: Element Visibility
6575
score: 8
6676
max: 8
6777
passed: true
68-
comment: Area fill and line are appropriately visible with good alpha
78+
comment: Area fill clearly visible with appropriate alpha, line weight 1.5
79+
well-suited for 30 data points, LOWESS trend line distinct
6980
- id: VQ-04
7081
name: Color Accessibility
7182
score: 5
7283
max: 5
7384
passed: true
74-
comment: Single blue color, no colorblind issues
85+
comment: 'Uses pyplots primary colors (#306998 blue, #FFD43B yellow) — colorblind-safe,
86+
high contrast'
7587
- id: VQ-05
7688
name: Layout Balance
7789
score: 5
7890
max: 5
7991
passed: true
80-
comment: Good proportions, no cut-off content
92+
comment: Plot fills canvas well in 16:9 ratio, balanced margins, no wasted
93+
space
8194
- id: VQ-06
8295
name: Axis Labels
83-
score: 1
96+
score: 2
8497
max: 2
85-
passed: false
86-
comment: '"Daily Visitors" and "Date" are descriptive but lack units'
98+
passed: true
99+
comment: 'X: Date (January 2024) with context, Y: Daily Visitors (count) with
100+
units'
87101
- id: VQ-07
88102
name: Grid & Legend
89103
score: 2
90104
max: 2
91105
passed: true
92-
comment: Grid is subtle (alpha 0.3), no legend needed for single series
106+
comment: 'Subtle major gridlines (alpha=0.3, #cccccc), minor grid removed,
107+
no legend needed for single series'
93108
spec_compliance:
94-
score: 25
109+
score: 24
95110
max: 25
96111
items:
97112
- id: SC-01
@@ -105,56 +120,58 @@ review:
105120
score: 5
106121
max: 5
107122
passed: true
108-
comment: X=datetime, Y=numeric correctly assigned
123+
comment: X=datetime dates, Y=numeric visitor counts — correctly assigned
109124
- id: SC-03
110125
name: Required Features
111126
score: 5
112127
max: 5
113128
passed: true
114-
comment: Semi-transparent fill, gridlines, clear axis labels all present
129+
comment: Semi-transparent fill (alpha 0.35), gridlines present, clear axis
130+
labels with units
115131
- id: SC-04
116132
name: Data Range
117133
score: 3
118134
max: 3
119135
passed: true
120-
comment: All data visible, Y-axis starts at 0
136+
comment: Y-axis 0–8,000+ shows all data; X-axis covers full 30-day range
121137
- id: SC-05
122138
name: Legend Accuracy
123-
score: 2
139+
score: 1
124140
max: 2
125-
passed: true
126-
comment: N/A for single series, no legend needed
141+
passed: false
142+
comment: Yellow LOWESS trend line has no legend entry; viewer may not understand
143+
what it represents
127144
- id: SC-06
128145
name: Title Format
129146
score: 2
130147
max: 2
131148
passed: true
132-
comment: Correctly formatted as "area-basic · plotnine · pyplots.ai"
149+
comment: area-basic · plotnine · pyplots.ai matches required format with middle
150+
dots
133151
data_quality:
134-
score: 18
152+
score: 19
135153
max: 20
136154
items:
137155
- id: DQ-01
138156
name: Feature Coverage
139157
score: 7
140158
max: 8
141159
passed: true
142-
comment: Shows trend, cyclical pattern, and volume well; could show more variation
143-
in amplitude
160+
comment: Shows upward trend, weekly cyclical pattern, increasing variance,
161+
clear peaks/troughs — comprehensive but could show wider range
144162
- id: DQ-02
145163
name: Realistic Context
146164
score: 7
147165
max: 7
148166
passed: true
149-
comment: Website traffic is a perfect real-world scenario with believable
150-
patterns
167+
comment: Daily website visitors over a month is a real, neutral business scenario
168+
matching the spec example
151169
- id: DQ-03
152170
name: Appropriate Scale
153-
score: 4
171+
score: 5
154172
max: 5
155173
passed: true
156-
comment: Values 4000-8000 daily visitors are realistic; starting Y at 0 is
157-
good but creates some empty space
174+
comment: 3,500–8,200 daily visitors is realistic for a mid-sized website
158175
code_quality:
159176
score: 10
160177
max: 10
@@ -164,40 +181,42 @@ review:
164181
score: 3
165182
max: 3
166183
passed: true
167-
comment: Simple imports → data → plot → save structure, no functions/classes
184+
comment: 'Clean linear flow: imports → data generation → plot → save, no functions/classes'
168185
- id: CQ-02
169186
name: Reproducibility
170187
score: 3
171188
max: 3
172189
passed: true
173-
comment: Uses np.random.seed(42)
190+
comment: np.random.seed(42) set before all random operations
174191
- id: CQ-03
175192
name: Clean Imports
176193
score: 2
177194
max: 2
178195
passed: true
179-
comment: All imports are used
196+
comment: All imports used (geom_smooth for LOWESS, annotate for Peak label,
197+
etc.)
180198
- id: CQ-04
181199
name: No Deprecated API
182200
score: 1
183201
max: 1
184202
passed: true
185-
comment: Uses current plotnine API
203+
comment: All API calls are current
186204
- id: CQ-05
187205
name: Output Correct
188206
score: 1
189207
max: 1
190208
passed: true
191209
comment: Saves as plot.png
192210
library_features:
193-
score: 2
211+
score: 4
194212
max: 5
195213
items:
196214
- id: LF-01
197-
name: Uses distinctive library features
198-
score: 2
215+
name: Distinctive Features
216+
score: 4
199217
max: 5
200-
passed: false
201-
comment: Uses ggplot grammar correctly but doesn't leverage plotnine-specific
202-
features like faceting or stat transformations
218+
passed: true
219+
comment: 'Effective grammar of graphics: layer composition (geom_area + geom_line
220+
+ geom_smooth), geom_smooth(method=lowess), scale_x_datetime, scale_y_continuous
221+
with custom lambda labels, annotate for text'
203222
verdict: APPROVED

0 commit comments

Comments
 (0)