Skip to content

Commit e4fd406

Browse files
feat(letsplot): implement rose-basic (#5599)
## Implementation: `rose-basic` - python/letsplot Implements the **python/letsplot** version of `rose-basic`. **File:** `plots/rose-basic/implementations/python/letsplot.py` **Parent Issue:** #1003 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/25152190302)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com>
1 parent cc9e1f0 commit e4fd406

2 files changed

Lines changed: 169 additions & 129 deletions

File tree

plots/rose-basic/implementations/python/letsplot.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
rose-basic: Basic Rose Chart
3-
Library: letsplot 4.8.2 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: letsplot 4.9.0 | Python 3.13.13
4+
Quality: 75/100 | Updated: 2026-04-30
55
"""
66

77
import pandas as pd
Lines changed: 166 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,164 +1,188 @@
11
library: letsplot
2+
language: python
23
specification_id: rose-basic
34
created: '2025-12-23T19:44:36Z'
4-
updated: '2025-12-23T19:50:56Z'
5-
generated_by: claude-opus-4-5-20251101
6-
workflow_run: 20469996773
7-
issue: 0
8-
python_version: 3.13.11
9-
library_version: 4.8.2
10-
preview_url: https://storage.googleapis.com/anyplot-images/plots/rose-basic/letsplot/plot.png
11-
preview_html: https://storage.googleapis.com/anyplot-images/plots/rose-basic/letsplot/plot.html
12-
quality_score: 91
13-
impl_tags:
14-
dependencies: []
15-
techniques:
16-
- html-export
17-
patterns:
18-
- data-generation
19-
dataprep: []
20-
styling: []
5+
updated: '2026-04-30T07:42:24Z'
6+
generated_by: claude-sonnet
7+
workflow_run: 25152190302
8+
issue: 1003
9+
python_version: 3.13.13
10+
library_version: 4.9.0
11+
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/letsplot/plot-light.png
12+
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/letsplot/plot-dark.png
13+
preview_html_light: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/letsplot/plot-light.html
14+
preview_html_dark: https://storage.googleapis.com/anyplot-images/plots/rose-basic/python/letsplot/plot-dark.html
15+
quality_score: 75
2116
review:
2217
strengths:
23-
- Excellent rose chart implementation using lets-plot coord_polar with geom_bar
24-
- Beautiful blue-to-yellow color gradient that follows Python brand colors and provides
25-
clear value differentiation
26-
- Proper month ordering using pd.Categorical to maintain natural calendar sequence
27-
- Clean code structure following KISS principles
28-
- Appropriate theme_minimal with well-tuned text sizes (24pt title, 18pt y-axis,
29-
16pt month labels)
30-
- Chart starts at January at top (12 o'clock) as recommended in spec for time data
18+
- Correct rose chart implementation using idiomatic lets-plot ggplot2 grammar with
19+
coord_polar()
20+
- Natural, neutral dataset (monthly rainfall) with plausible seasonal pattern and
21+
appropriate scale (65-168mm/month)
22+
- Clean KISS code structure; all imports used; fully deterministic hardcoded data
23+
- Removing angular grid spokes (panel_grid_major_x=element_blank()) is a good refinement
24+
for polar charts
25+
- Both theme renders show visually acceptable output with warm off-white / near-black
26+
backgrounds and readable text
3127
weaknesses:
32-
- Radial gridlines (panel_grid_major_y) could be more subtle with lower alpha for
33-
cleaner appearance
34-
- The y-axis title appears on the left side which is slightly awkward for polar
35-
coordinates
36-
image_description: The plot displays a rose chart (polar bar chart) showing monthly
37-
rainfall distribution. The chart is centered on the canvas with months arranged
38-
clockwise starting from January at the top (12 o'clock position). Each wedge represents
39-
a month with the radius proportional to rainfall amount. Colors transition smoothly
40-
from Python Blue (#306998) for winter months through greens and yellows to Python
41-
Yellow (#FFD43B) for December. July has the longest bar (168mm), while February
42-
has the shortest (65mm). The title reads "Monthly Rainfall Distribution · rose-basic
43-
· letsplot · pyplots.ai" in bold at the top. Radial gridlines are visible at 20mm
44-
intervals (0, 20, 40, 60, 80, 100, 120, 140, 160). The y-axis label "Rainfall
45-
(mm)" appears on the left side. Month labels are positioned around the outer edge
46-
of the chart.
28+
- 'Non-Okabe-Ito palette: code uses Python Blue-to-Yellow gradient starting with
29+
#306998 (explicitly prohibited); replace with single geom_bar(fill=''#009E73'')
30+
since all bars represent the same metric'
31+
- 'Missing theme adaptation: no os.getenv(''ANYPLOT_THEME'') logic, no PAGE_BG/INK/INK_SOFT
32+
tokens applied to plot_background, panel_background, axis_text, axis_title, plot_title'
33+
- 'Wrong output filenames: saves plot.png/plot.html instead of plot-{THEME}.png/plot-{THEME}.html
34+
as required by the pipeline'
35+
- Title contains 'pyplots.ai' instead of 'anyplot.ai' in the code (images show correct
36+
value, suggesting code/image version mismatch)
37+
- 'Font sizes below guidelines: axis_title_y=18pt (should be >=20pt) and axis_text_y=14pt
38+
(should be >=16pt)'
39+
image_description: |-
40+
Light render (plot-light.png):
41+
Background: Warm off-white (~#FAF8F1) - not pure white, consistent with anyplot light theme
42+
Chrome: Title "Monthly Rainfall Distribution - rose-basic - letsplot - anyplot.ai" in bold dark text at top (readable); month labels Jan-Dec around perimeter in dark text (readable); radial axis ticks 0/20/40/60/80/100/120/140/160 in darker text (readable); y-axis label "Rainfall (mm)" on left (readable)
43+
Data: All 12 monthly rose segments in single teal-green color (~#009E73); radial gridlines visible as concentric circles; segments clearly distinguishable from background
44+
Legibility verdict: PASS - all text readable against warm off-white background, no light-on-light failures
45+
46+
Dark render (plot-dark.png):
47+
Background: Warm near-black (~#1A1A17) - not pure black, consistent with anyplot dark theme
48+
Chrome: Title in lighter text (readable against dark background); month labels around perimeter in lighter text (readable); radial axis ticks in lighter text (readable); y-axis label in lighter text (readable); no dark-on-dark text failures detected
49+
Data: Same teal-green segments as light render - colors identical between themes, only chrome flipped; segments remain clearly visible against dark background
50+
Legibility verdict: PASS - all text readable against near-black background, no dark-on-dark failures observed
4751
criteria_checklist:
4852
visual_quality:
49-
score: 36
50-
max: 40
53+
score: 25
54+
max: 30
5155
items:
5256
- id: VQ-01
5357
name: Text Legibility
54-
score: 9
55-
max: 10
58+
score: 6
59+
max: 8
5660
passed: true
57-
comment: Title at 24pt, axis text at 16pt, all clearly readable. Slightly
58-
crowded month labels but acceptable.
61+
comment: Title=24pt bold explicitly set; axis_text_x=16pt; axis_title_y=18pt
62+
(below 20pt guideline); axis_text_y=14pt (below 16pt guideline); images
63+
show readable text in both themes but code lacks color adaptation
5964
- id: VQ-02
6065
name: No Overlap
61-
score: 8
62-
max: 8
66+
score: 6
67+
max: 6
6368
passed: true
64-
comment: No overlapping text elements
69+
comment: 12 month labels evenly spaced around perimeter, no collisions observed
6570
- id: VQ-03
6671
name: Element Visibility
67-
score: 7
68-
max: 8
72+
score: 6
73+
max: 6
6974
passed: true
70-
comment: Bars are well-sized with 0.85 alpha, good visibility. Slightly tight
71-
spacing between adjacent bars.
75+
comment: Rose segments clearly visible with good size and contrast in both
76+
themes
7277
- id: VQ-04
7378
name: Color Accessibility
74-
score: 5
75-
max: 5
79+
score: 2
80+
max: 2
7681
passed: true
77-
comment: Gradient from blue to yellow is colorblind-safe, no red-green dependency
82+
comment: Single teal-green series is CVD-safe with high contrast against both
83+
backgrounds
7884
- id: VQ-05
79-
name: Layout Balance
80-
score: 5
81-
max: 5
85+
name: Layout & Canvas
86+
score: 3
87+
max: 4
8288
passed: true
83-
comment: Rose chart is well-centered, fills ~60% of canvas, balanced margins
89+
comment: Rose chart fills canvas well; some corner waste typical of polar/circular
90+
charts in landscape format
8491
- id: VQ-06
85-
name: Axis Labels
92+
name: Axis Labels & Title
8693
score: 2
8794
max: 2
8895
passed: true
89-
comment: Y-axis labeled "Rainfall (mm)" with units, x-axis appropriately blank
96+
comment: Rainfall (mm) with units; descriptive title present
9097
- id: VQ-07
91-
name: Grid & Legend
98+
name: Palette Compliance
9299
score: 0
93100
max: 2
101+
passed: false
102+
comment: 'Code contains #306998 (Python Blue) as first color - explicitly
103+
prohibited; 12-color custom gradient is not Okabe-Ito; no os.getenv(ANYPLOT_THEME)
104+
means no theme-adaptive chrome in code'
105+
design_excellence:
106+
score: 9
107+
max: 20
108+
items:
109+
- id: DE-01
110+
name: Aesthetic Sophistication
111+
score: 4
112+
max: 8
113+
passed: true
114+
comment: Single-color rose chart has clean appeal; well-configured library
115+
default look; not publication-exceptional
116+
- id: DE-02
117+
name: Visual Refinement
118+
score: 3
119+
max: 6
94120
passed: true
95-
comment: Legend disabled (appropriate), but radial gridlines could be more
96-
subtle
121+
comment: panel_grid_major_x=element_blank() removes angular spokes; radial
122+
gridlines appropriate; minimal further polish
123+
- id: DE-03
124+
name: Data Storytelling
125+
score: 2
126+
max: 6
127+
passed: false
128+
comment: Seasonal pattern visible naturally but no visual emphasis; single-color
129+
prevents hierarchical storytelling
97130
spec_compliance:
98-
score: 25
99-
max: 25
131+
score: 13
132+
max: 15
100133
items:
101134
- id: SC-01
102135
name: Plot Type
103-
score: 8
104-
max: 8
105-
passed: true
106-
comment: Correct rose/coxcomb chart using polar coordinates
107-
- id: SC-02
108-
name: Data Mapping
109136
score: 5
110137
max: 5
111138
passed: true
112-
comment: Months on angular axis, rainfall on radial axis correctly
113-
- id: SC-03
139+
comment: 'Correct rose chart: polar coordinates, equal-angle wedges, radius
140+
proportional to value'
141+
- id: SC-02
114142
name: Required Features
115-
score: 5
116-
max: 5
143+
score: 4
144+
max: 4
117145
passed: true
118-
comment: 'All spec features present: equal-angle wedges, radius proportional
119-
to value, radial gridlines'
120-
- id: SC-04
121-
name: Data Range
146+
comment: Circular layout, Jan at 12 o'clock, radial gridlines, consistent
147+
color scheme all present
148+
- id: SC-03
149+
name: Data Mapping
122150
score: 3
123151
max: 3
124152
passed: true
125-
comment: All data visible within the chart bounds
126-
- id: SC-05
127-
name: Legend Accuracy
128-
score: 2
129-
max: 2
130-
passed: true
131-
comment: Legend correctly disabled (colors are per-month gradient, self-explanatory)
132-
- id: SC-06
133-
name: Title Format
134-
score: 2
135-
max: 2
136-
passed: true
137-
comment: Follows "{description} · {spec-id} · {library} · pyplots.ai" format
153+
comment: Months mapped to angular positions, rainfall (mm) mapped to radius
154+
- id: SC-04
155+
name: Title & Legend
156+
score: 1
157+
max: 3
158+
passed: false
159+
comment: Code title reads '...pyplots.ai' instead of '...anyplot.ai'; image
160+
shows correct value suggesting version mismatch; scored on current code
138161
data_quality:
139-
score: 18
140-
max: 20
162+
score: 14
163+
max: 15
141164
items:
142165
- id: DQ-01
143166
name: Feature Coverage
144-
score: 7
145-
max: 8
167+
score: 5
168+
max: 6
146169
passed: true
147-
comment: Shows seasonal rainfall pattern with summer peak (Jul=168mm) and
148-
winter trough (Feb=65mm). Good variation across months.
170+
comment: 12-month cycle shows full seasonal variation; winter-low/summer-high
171+
pattern illustrated; slight deduction for moderate value range
149172
- id: DQ-02
150173
name: Realistic Context
151-
score: 7
152-
max: 7
174+
score: 5
175+
max: 5
153176
passed: true
154-
comment: Monthly rainfall is a realistic application mentioned in spec
177+
comment: Monthly rainfall is natural, neutral, comprehensible; no controversial
178+
content
155179
- id: DQ-03
156180
name: Appropriate Scale
157181
score: 4
158-
max: 5
182+
max: 4
159183
passed: true
160-
comment: Rainfall values 65-168mm are plausible for temperate climate, though
161-
slightly high for some months
184+
comment: Values 65-168mm/month plausible for temperate climate; proportions
185+
factually reasonable
162186
code_quality:
163187
score: 9
164188
max: 10
@@ -168,41 +192,57 @@ review:
168192
score: 3
169193
max: 3
170194
passed: true
171-
comment: Clean imports → data → plot → save structure, no functions/classes
195+
comment: Imports -> Data -> Plot -> Save; no functions or classes
172196
- id: CQ-02
173197
name: Reproducibility
174198
score: 2
175-
max: 3
199+
max: 2
176200
passed: true
177-
comment: 'Data is deterministic (hardcoded), but np.random.seed not needed.
178-
Minor: no explicit seed statement.'
201+
comment: All data hardcoded; fully deterministic
179202
- id: CQ-03
180203
name: Clean Imports
181204
score: 2
182205
max: 2
183206
passed: true
184-
comment: All imports are used
207+
comment: All imported symbols are used
185208
- id: CQ-04
186-
name: No Deprecated API
187-
score: 1
188-
max: 1
209+
name: Code Elegance
210+
score: 2
211+
max: 2
189212
passed: true
190-
comment: Uses current lets-plot API
213+
comment: Clean, Pythonic structure; no fake UI elements
191214
- id: CQ-05
192-
name: Output Correct
193-
score: 1
215+
name: Output & API
216+
score: 0
194217
max: 1
195-
passed: true
196-
comment: Saves as plot.png and plot.html
197-
library_features:
198-
score: 3
199-
max: 5
218+
passed: false
219+
comment: Saves as plot.png/plot.html (bare filenames) instead of plot-{THEME}.png/plot-{THEME}.html;
220+
no ANYPLOT_THEME env var read
221+
library_mastery:
222+
score: 5
223+
max: 10
200224
items:
201-
- id: LF-01
202-
name: Uses distinctive library features
225+
- id: LM-01
226+
name: Idiomatic Usage
203227
score: 3
204228
max: 5
205229
passed: true
206-
comment: Uses lets-plot's ggplot grammar with coord_polar, scale_fill_manual,
207-
and theme customization. Could leverage more interactive features.
230+
comment: ggplot+geom_bar+coord_polar is correct ggplot2-grammar approach;
231+
ggsize() and ggsave(scale=3) used idiomatically; misses required theme-adaptive
232+
chrome pattern
233+
- id: LM-02
234+
name: Distinctive Features
235+
score: 2
236+
max: 5
237+
passed: false
238+
comment: ggsize() and scaled ggsave() are lets-plot specific; core coord_polar+geom_bar
239+
pattern shared with plotnine; no notably distinctive lets-plot features
208240
verdict: APPROVED
241+
impl_tags:
242+
dependencies: []
243+
techniques:
244+
- polar-projection
245+
patterns: []
246+
dataprep: []
247+
styling:
248+
- alpha-blending

0 commit comments

Comments
 (0)