Skip to content

Commit c738b90

Browse files
chore(matplotlib): update quality score 87 and review feedback for lollipop-basic
1 parent 7fb8de2 commit c738b90

2 files changed

Lines changed: 97 additions & 99 deletions

File tree

plots/lollipop-basic/implementations/python/matplotlib.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
"""anyplot.ai
1+
""" anyplot.ai
22
lollipop-basic: Basic Lollipop Chart
33
Library: matplotlib 3.11.0 | Python 3.13.14
4-
Quality: 85/100 | Updated: 2026-07-01
4+
Quality: 87/100 | Updated: 2026-07-01
55
"""
66

77
import os

plots/lollipop-basic/metadata/python/matplotlib.yaml

Lines changed: 95 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ library: matplotlib
22
language: python
33
specification_id: lollipop-basic
44
created: '2025-12-23T15:33:44Z'
5-
updated: '2026-07-01T06:00:37Z'
5+
updated: '2026-07-01T06:10:07Z'
66
generated_by: claude-sonnet
77
workflow_run: 28496285913
88
issue: 934
@@ -12,158 +12,157 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/lollipop-
1212
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/lollipop-basic/python/matplotlib/plot-dark.png
1313
preview_html_light: null
1414
preview_html_dark: null
15-
quality_score: 85
15+
quality_score: 87
1616
review:
1717
strengths:
18-
- 'Correct lollipop chart type: stems via ax.vlines, markers via ax.scatter, vertical
19-
orientation, baseline-to-value design'
20-
- 'Good data storytelling: descending sort creates natural ranking narrative, average
21-
reference line anchors comparison, ''Top performer'' callout annotation with arrow
22-
creates focal point'
23-
- Brand green (#009E73) correctly used as single series color; differential marker
24-
size (s=120 top vs s=80 rest) adds emphasis
25-
- Theme-adaptive chrome correctly and completely implemented — all text, background,
26-
grid, annotation box tokens flip between themes
27-
- 'Clean code: no functions/classes, deterministic data, correct matplotlib axes
28-
API, no bbox_inches=''tight'' (respects canvas gate)'
18+
- 'Perfect spec compliance: correct lollipop chart with stems (ax.vlines) and circular
19+
markers (ax.scatter) in vertical orientation with data sorted descending by value'
20+
- 'Correct Imprint palette usage: brand green #009E73 for both stems and markers;
21+
theme-adaptive backgrounds (#FAF8F1 light / #1A1A17 dark) and full INK/INK_SOFT/INK_MUTED
22+
chrome token threading'
23+
- 'Intentional visual hierarchy: slightly larger top-performer marker (s=120 vs
24+
s=80), plus ''Top performer'' annotation with arrowprops, plus average reference
25+
line — creates a clear ranking narrative'
26+
- 'Idiomatic matplotlib usage: ax.vlines() for stems, ax.scatter() for markers,
27+
ax.annotate() with arrowprops, mticker.FuncFormatter for y-axis formatting, fig.subplots_adjust()
28+
to control layout without bbox_inches=''tight'''
29+
- 'Perfect code quality: clean KISS structure, all imports used, deterministic data,
30+
saves as plot-{THEME}.png'
31+
- Both light and dark renders fully readable with no dark-on-dark or light-on-light
32+
failures
2933
weaknesses:
30-
- 'Title missing ''python'' language identifier: should be ''lollipop-basic · python
31-
· matplotlib · anyplot.ai'' — the {language} token is required by SC-04'
32-
- Value labels (fontsize=6.5) and avg reference label (fontsize=6) are too small
33-
at mobile scale (~400px); increase value labels to fontsize=8 and avg label to
34-
fontsize=7.5
35-
- X-axis label 'Product Category' is at the bottom canvas edge with bottom margin
36-
too tight; increase subplots_adjust(bottom=0.22) to bottom=0.26 to ensure the
37-
xlabel does not touch or clip the canvas edge
34+
- Annotation text at fontsize=6.5 and avg-line label at fontsize=7.5 are borderline
35+
at mobile scale (~400px viewport) — tertiary elements but still worth bumping
36+
to 8pt minimum
37+
- 'DE-01 is at default level: the chart is clean but aesthetic sophistication could
38+
be elevated — e.g., subtle gradient on stems from baseline to marker tip, or per-category
39+
color intensity to encode rank'
40+
- 'LM-02: only two genuinely matplotlib-distinctive features used (mticker.FuncFormatter,
41+
ax.annotate with arrowprops) — could showcase more library depth (e.g., matplotlib.patches
42+
for custom connectors, BboxTransformTo for annotation positioning, or a PathEffect
43+
for the stems)'
3844
image_description: |-
3945
Light render (plot-light.png):
40-
Background: Warm off-white #FAF8F1 — correct, not pure white
41-
Chrome: Title "lollipop-basic · matplotlib · anyplot.ai" in dark ink readable. Y-axis label "Sales (thousands)" in dark ink — readable with units. X-axis label "Product Category" present but very close to bottom canvas edge with possible pixel clipping. Tick labels rotated 45° in secondary ink (#4A4A44) — readable. Y-axis numeric tick labels in secondary ink — readable.
42-
Data: Ten brand-green (#009E73) lollipops; stems via vlines, circular markers via scatter. Value labels (fontsize=6.5) above each marker showing 87K...25K. Dashed average line at 52K with "avg 52K" label (fontsize=6 — very small). "Top performer" callout annotation box with arrow pointing to Electronics dot.
43-
Legibility verdict: PASS for main chrome; value labels and avg label are very small at mobile scale; x-axis label near bottom canvas edge.
46+
Background: Warm off-white (#FAF8F1) — correct, not pure white
47+
Chrome: Title "lollipop-basic · python · matplotlib · anyplot.ai" in dark ink at 12pt, readable. X-axis label "Product Category" and Y-axis label "Sales (thousands)" in dark ink at 10pt, readable. Tick labels rotated 45° at 8pt, all fully readable. Y-axis ticks (0, 20, 40, 60, 80, 100, 120) in INK_SOFT gray, readable. Average line label "avg 52K" in INK_MUTED at 7.5pt — small but legible at full resolution.
48+
Data: Brand green (#009E73) stems (linewidth=2) and filled circular markers for all 10 retail categories. Top-performer marker (Electronics, 87K) slightly larger (s=120 vs s=80). Value labels "87K", "72K"... in INK_SOFT at 8pt above each marker. Dashed average reference line in INK_MUTED. "Top performer" annotation box with arrow pointing to Electronics lollipop.
49+
Legibility verdict: PASS — all primary and secondary text clearly readable; annotation at 6.5pt is the only element approaching the mobile-readability limit.
4450
4551
Dark render (plot-dark.png):
46-
Background: Warm near-black #1A1A17 — correct, not pure black
47-
Chrome: Title in near-white (#F0EFE8) — readable. Y-axis label in near-white — readable. Tick labels in #B8B7B0 — readable against dark background. No dark-on-dark text failures detected. "Top performer" annotation box uses ELEVATED_BG (#242420) with INK (#F0EFE8) text — correctly adapted for dark theme. Avg line label in INK_MUTED (#A8A79F) — subtle but visible.
48-
Data: Same brand-green (#009E73) lollipops — colors identical to light render; only chrome flipped. Grid lines use INK at alpha=0.15 — appropriately subtle light lines on dark background.
49-
Legibility verdict: PASS for main chrome; same small-font concern for value/avg labels; x-axis label near bottom canvas edge.
52+
Background: Warm near-black (#1A1A17) — correct, not pure black
53+
Chrome: Title and axis labels appear in light color (INK=#F0EFE8 in dark mode), clearly readable against dark surface. Tick labels in INK_SOFT (#B8B7B0)visible and legible. Average line label "avg 52K" in INK_MUTED (#A8A79F), readable. "Top performer" annotation box uses ELEVATED_BG (#242420) fill with light INK text — correct adaptation.
54+
Data: Stem and marker colors identical to light render (brand green #009E73 unchanged) — Imprint palette consistency confirmed. No difference in data colors between themes.
55+
Legibility verdict: PASS — no dark-on-dark failures; all chrome elements flip correctly; data colors are theme-invariant as required.
5056
criteria_checklist:
5157
visual_quality:
52-
score: 26
58+
score: 29
5359
max: 30
5460
items:
5561
- id: VQ-01
5662
name: Text Legibility
57-
score: 6
63+
score: 7
5864
max: 8
5965
passed: true
60-
comment: Title, axis labels, tick labels explicitly sized and readable at
61-
desktop resolution. Value labels (fontsize=6.5) and avg reference label
62-
(fontsize=6) too small for mobile scale (~400px wide). Increase value labels
63-
to 8pt and avg label to 7.5pt.
66+
comment: All primary/secondary text sizes explicitly set and readable in both
67+
themes; annotation at 6.5pt is borderline at mobile scale
6468
- id: VQ-02
6569
name: No Overlap
6670
score: 6
6771
max: 6
6872
passed: true
69-
comment: No overlapping text or data elements in either render.
73+
comment: No overlapping elements; 45-degree rotated tick labels well-spaced;
74+
value labels clear of markers
7075
- id: VQ-03
7176
name: Element Visibility
72-
score: 5
77+
score: 6
7378
max: 6
7479
passed: true
75-
comment: Lollipop stems and markers clearly visible. Differential marker sizing
76-
(s=120 top vs s=80 rest) adds emphasis. Could be slightly larger (s=100/s=140)
77-
for better mobile visibility.
80+
comment: Sparse 10-point dataset; s=80-120 markers well-sized; stems at linewidth=2.0
81+
clearly visible; edge highlighting adds definition
7882
- id: VQ-04
7983
name: Color Accessibility
8084
score: 2
8185
max: 2
8286
passed: true
83-
comment: Single-series brand green with good contrast on both surfaces; CVD-safe.
87+
comment: Single-series in CVD-safe brand green; no red-green sole signal
8488
- id: VQ-05
8589
name: Layout & Canvas
86-
score: 3
90+
score: 4
8791
max: 4
8892
passed: true
89-
comment: 'Proportions generally good. Minor concern: x-axis label ''Product
90-
Category'' at bottom canvas edge with bottom margin too tight (0.22). Increase
91-
to 0.26.'
93+
comment: Canvas gate passed (3200x1800); subplots_adjust gives generous margins;
94+
plot fills canvas well
9295
- id: VQ-06
9396
name: Axis Labels & Title
9497
score: 2
9598
max: 2
9699
passed: true
97-
comment: '''Product Category'' and ''Sales (thousands)'' — descriptive with
98-
units.'
100+
comment: Title correct format; 'Product Category' and 'Sales (thousands)'
101+
descriptive with units
99102
- id: VQ-07
100103
name: Palette Compliance
101104
score: 2
102105
max: 2
103106
passed: true
104-
comment: 'First (and only) series is #009E73. Light background #FAF8F1, dark
105-
background #1A1A17. All chrome tokens correctly theme-adaptive in both renders.'
107+
comment: 'First series #009E73; backgrounds #FAF8F1/#1A1A17; all chrome tokens
108+
adapt correctly across themes'
106109
design_excellence:
107-
score: 13
110+
score: 12
108111
max: 20
109112
items:
110113
- id: DE-01
111114
name: Aesthetic Sophistication
112-
score: 5
115+
score: 4
113116
max: 8
114-
passed: true
115-
comment: 'Above generic defaults: sorted ranking, larger top-performer dot,
116-
callout annotation with arrow, average reference line create a designed
117-
narrative. Not FiveThirtyEight-level but clearly intentional.'
117+
passed: false
118+
comment: 'Well-configured default: clean, correct, uses INK hierarchy and
119+
edge highlighting, but no advanced typographic or compositional moves beyond
120+
standard'
118121
- id: DE-02
119122
name: Visual Refinement
120123
score: 4
121124
max: 6
122125
passed: true
123-
comment: Top/right spines removed, subtle y-axis-only grid at alpha=0.15,
124-
white marker edges for definition, theme-adaptive chrome. Solid refinement.
126+
comment: Spines removed (top/right); y-axis-only grid at alpha=0.15; set_axisbelow;
127+
INK_SOFT spine color; edge highlights on markers
125128
- id: DE-03
126129
name: Data Storytelling
127130
score: 4
128131
max: 6
129132
passed: true
130-
comment: Clear ranking story via descending sort. Average line anchors viewer
131-
reference. 'Top performer' callout creates explicit focal point. Value labels
132-
enable exact figure reading.
133+
comment: Sorted ranking creates narrative; average reference line for context;
134+
focal point via larger top-performer marker + annotation
133135
spec_compliance:
134-
score: 14
136+
score: 15
135137
max: 15
136138
items:
137139
- id: SC-01
138140
name: Plot Type
139141
score: 5
140142
max: 5
141143
passed: true
142-
comment: 'Correct lollipop: thin stems (ax.vlines) from baseline to value,
143-
circular markers (ax.scatter) at each data point, vertical orientation.'
144+
comment: 'Correct lollipop chart: ax.vlines() stems + ax.scatter() markers
145+
in vertical orientation'
144146
- id: SC-02
145147
name: Required Features
146148
score: 4
147149
max: 4
148150
passed: true
149-
comment: Stems present, markers present, vertical orientation, data sorted
150-
by value descending.
151+
comment: Stems, circular markers, vertical orientation, sorted by value —
152+
all present
151153
- id: SC-03
152154
name: Data Mapping
153155
score: 3
154156
max: 3
155157
passed: true
156-
comment: Categories on x-axis, sales values on y-axis, all 10 data points
157-
shown.
158+
comment: Categories on x-axis, values on y-axis, all 10 points shown
158159
- id: SC-04
159160
name: Title & Legend
160-
score: 2
161+
score: 3
161162
max: 3
162-
passed: false
163-
comment: 'Title is ''lollipop-basic · matplotlib · anyplot.ai'' but required
164-
format is ''{spec-id} · {language} · {library} · anyplot.ai''. The ''python''
165-
language identifier is missing. Fix: title = ''lollipop-basic · python ·
166-
matplotlib · anyplot.ai''.'
163+
passed: true
164+
comment: Title 'lollipop-basic · python · matplotlib · anyplot.ai' correct;
165+
no legend (single series, correct to omit)
167166
data_quality:
168167
score: 15
169168
max: 15
@@ -173,21 +172,22 @@ review:
173172
score: 6
174173
max: 6
175174
passed: true
176-
comment: 'Shows all essential lollipop features: stems, markers, sorted ranking,
177-
range of values, baseline-to-dot visual.'
175+
comment: 'Shows all lollipop aspects: stems, markers, baseline, sorting; value
176+
labels and reference line add context'
178177
- id: DQ-02
179178
name: Realistic Context
180179
score: 5
181180
max: 5
182181
passed: true
183-
comment: Retail sales by category is a real-world, neutral business scenario
184-
with recognizable category labels.
182+
comment: Retail category sales — neutral, realistic, named categories (not
183+
abstract)
185184
- id: DQ-03
186185
name: Appropriate Scale
187186
score: 4
188187
max: 4
189188
passed: true
190-
comment: Values 25-87K for retail category sales are realistic and well-spread.
189+
comment: 25-87K range plausible for retail; y-axis from 0 correct for this
190+
chart type
191191
code_quality:
192192
score: 10
193193
max: 10
@@ -197,56 +197,54 @@ review:
197197
score: 3
198198
max: 3
199199
passed: true
200-
comment: 'Linear: imports -> constants -> data -> plot -> save. No functions
201-
or classes.'
200+
comment: 'Linear structure: imports data plot save; no functions or
201+
classes'
202202
- id: CQ-02
203203
name: Reproducibility
204204
score: 2
205205
max: 2
206206
passed: true
207-
comment: Fully deterministic hardcoded data; no random generation.
207+
comment: Fully hardcoded deterministic data; no random elements
208208
- id: CQ-03
209209
name: Clean Imports
210210
score: 2
211211
max: 2
212212
passed: true
213-
comment: os, matplotlib.pyplot, matplotlib.ticker, numpy — all used.
213+
comment: All 4 imports (os, matplotlib.pyplot, matplotlib.ticker, numpy) are
214+
used
214215
- id: CQ-04
215216
name: Code Elegance
216217
score: 2
217218
max: 2
218219
passed: true
219-
comment: Clean Pythonic code; np.where for conditional marker sizes is concise;
220-
FuncFormatter for y-tick formatting is elegant.
220+
comment: Clean Pythonic code; no fake interactivity; appropriate complexity
221221
- id: CQ-05
222222
name: Output & API
223223
score: 1
224224
max: 1
225225
passed: true
226-
comment: Saves as plot-{THEME}.png with correct dpi; no bbox_inches='tight'
227-
(correct for canvas gate).
226+
comment: Saves plot-{THEME}.png; no bbox_inches='tight'; current matplotlib
227+
API
228228
library_mastery:
229-
score: 7
229+
score: 6
230230
max: 10
231231
items:
232232
- id: LM-01
233233
name: Idiomatic Usage
234234
score: 4
235235
max: 5
236236
passed: true
237-
comment: Correct axes-method API throughout (ax.vlines, ax.scatter, ax.annotate,
238-
ax.axhline). FuncFormatter from matplotlib.ticker used idiomatically. subplots_adjust
239-
used correctly to avoid bbox_inches='tight' drift.
237+
comment: ax.vlines() for stems, ax.scatter() with edge params, ax.annotate()
238+
with arrowprops, ax.axhline(), FuncFormatter, fig.subplots_adjust() — all
239+
correct idiomatic patterns
240240
- id: LM-02
241241
name: Distinctive Features
242-
score: 3
242+
score: 2
243243
max: 5
244-
passed: true
245-
comment: ax.vlines is the canonical matplotlib stem API for lollipops. ax.annotate
246-
with arrowprops is distinctly matplotlib. mticker.FuncFormatter is library-specific.
247-
Good use but not pushing into territory that truly couldn't be replicated
248-
elsewhere.
249-
verdict: REJECTED
244+
passed: false
245+
comment: mticker.FuncFormatter and ax.annotate with arrowprops are matplotlib-specific,
246+
but usage is moderate; could showcase more library depth
247+
verdict: APPROVED
250248
impl_tags:
251249
dependencies: []
252250
techniques:

0 commit comments

Comments
 (0)