Skip to content

Commit f5bdf40

Browse files
feat(makie): implement rose-basic (#9830)
## Implementation: `rose-basic` - julia/makie Implements the **julia/makie** version of `rose-basic`. **File:** `plots/rose-basic/implementations/julia/makie.jl` **Parent Issue:** #1003 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/30154441735)* --------- 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 c469940 commit f5bdf40

2 files changed

Lines changed: 346 additions & 0 deletions

File tree

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# anyplot.ai
2+
# rose-basic: Basic Rose Chart
3+
# Library: makie 0.21.9 | Julia 1.11.9
4+
# Quality: 91/100 | Created: 2026-07-25
5+
6+
using CairoMakie
7+
using Colors
8+
using Random
9+
10+
Random.seed!(42)
11+
12+
# --- Theme tokens -----------------------------------------------------------
13+
const THEME = get(ENV, "ANYPLOT_THEME", "light")
14+
const PAGE_BG = THEME == "light" ? colorant"#FAF8F1" : colorant"#1A1A17"
15+
const INK = THEME == "light" ? colorant"#1A1A17" : colorant"#F0EFE8"
16+
const INK_SOFT = THEME == "light" ? colorant"#4A4A44" : colorant"#B8B7B0"
17+
const IMPRINT_PALETTE = [
18+
colorant"#009E73", colorant"#C475FD", colorant"#4467A3", colorant"#BD8233",
19+
colorant"#AE3030", colorant"#2ABCCD", colorant"#954477", colorant"#99B314",
20+
]
21+
22+
# --- Data ---------------------------------------------------------------
23+
# Monthly rainfall for a temperate coastal city — wetter autumn/winter,
24+
# drier summer, a natural 12-month cycle where the circular layout maps
25+
# directly onto the calendar.
26+
months = [
27+
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
28+
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec",
29+
]
30+
n_months = length(months)
31+
base_rainfall_mm = [82, 68, 74, 58, 52, 41, 33, 38, 54, 71, 88, 95]
32+
rainfall_mm = base_rainfall_mm .+ randn(n_months) .* 4
33+
34+
# --- Plot -----------------------------------------------------------------
35+
fig = Figure(
36+
resolution = (1200, 1200),
37+
fontsize = 14,
38+
backgroundcolor = PAGE_BG,
39+
)
40+
41+
ax = PolarAxis(
42+
fig[1, 1];
43+
theta_0 = -pi / 2, # January starts at 12 o'clock
44+
direction = -1, # clockwise, matching calendar order
45+
backgroundcolor = PAGE_BG,
46+
title = "Monthly Rainfall · rose-basic · julia · makie · anyplot.ai",
47+
titlesize = 20,
48+
titlecolor = INK,
49+
thetaticks = (range(0, 2pi, length = n_months + 1)[1:n_months], months),
50+
thetaticklabelsize = 14,
51+
thetaticklabelcolor = INK_SOFT,
52+
thetagridvisible = false,
53+
rticks = 0:20:100,
54+
rtickformat = vs -> ["$(round(Int, v)) mm" for v in vs],
55+
rtickangle = 13pi / 12, # Jul–Aug gap — the driest wedges, keeps labels off the tall bars
56+
rticklabelsize = 15,
57+
rticklabelcolor = INK_SOFT,
58+
rgridvisible = true,
59+
rgridcolor = RGBAf(INK.r, INK.g, INK.b, 0.15),
60+
rgridwidth = 1,
61+
spinecolor = INK_SOFT,
62+
spinewidth = 1,
63+
rlimits = (0, 110),
64+
)
65+
66+
# Equal-angle wedges, radius proportional to value — filled with `band!`
67+
# since it (unlike `poly!`) respects the PolarAxis per-vertex transform
68+
# and traces a true curved arc rather than a straight-edged rectangle.
69+
# Fill alpha is ramped by value (spec's "varying saturation" option) so the
70+
# wettest months read as the visual focal point; the peak/trough wedges also
71+
# get a heavier outline as an explicit callout for the seasonal story.
72+
theta = range(0, 2pi, length = n_months + 1)[1:n_months]
73+
half_width = (2pi / n_months) * 0.9 / 2
74+
n_arc_samples = 40
75+
rmin, rmax = extrema(rainfall_mm)
76+
peak_idx, trough_idx = argmax(rainfall_mm), argmin(rainfall_mm)
77+
78+
for (i, (t, rv)) in enumerate(zip(theta, rainfall_mm))
79+
ts = collect(range(t - half_width, t + half_width, length = n_arc_samples))
80+
alpha = 0.55 + 0.45 * (rv - rmin) / (rmax - rmin)
81+
wedge_color = RGBAf(IMPRINT_PALETTE[1].r, IMPRINT_PALETTE[1].g, IMPRINT_PALETTE[1].b, alpha)
82+
band!(
83+
ax, ts, zeros(n_arc_samples), fill(rv, n_arc_samples);
84+
color = wedge_color,
85+
)
86+
87+
if i == peak_idx || i == trough_idx
88+
outline_theta = vcat(t - half_width, ts, t + half_width)
89+
outline_r = vcat(0.0, fill(rv, n_arc_samples), 0.0)
90+
lines!(ax, outline_theta, outline_r; color = INK, linewidth = 2.5)
91+
end
92+
end
93+
94+
# --- Save -------------------------------------------------------------------
95+
save("plot-$(THEME).png", fig; px_per_unit = 2)
Lines changed: 251 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,251 @@
1+
library: makie
2+
language: julia
3+
specification_id: rose-basic
4+
created: '2026-07-25T10:39:48Z'
5+
updated: '2026-07-25T10:59:44Z'
6+
generated_by: claude-sonnet
7+
workflow_run: 30154441735
8+
issue: 1003
9+
language_version: 1.11.9
10+
library_version: 0.21.9
11+
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/rose-basic/julia/makie/plot-light.png
12+
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/rose-basic/julia/makie/plot-dark.png
13+
preview_html_light: null
14+
preview_html_dark: null
15+
quality_score: 91
16+
review:
17+
strengths:
18+
- Alpha ramp keyed to value (0.55-1.0) plus outline strokes on the peak (Dec) and
19+
trough (Jul) wedges directly address the prior attempt's Design Excellence feedback,
20+
giving the chart a clear focal point without breaking the spec's 'consistent color
21+
scheme, single color with varying saturation' guidance
22+
- rticklabelsize bumped from 12 to 15, resolving the prior attempt's mobile-legibility
23+
weakness on radial tick labels
24+
- 'Correct rose/coxcomb geometry: equal-angle wedges via band! sampled over 40 arc
25+
points per wedge, radius (not area) proportional to value, true curved edges exploiting
26+
PolarAxis''s per-vertex transform'
27+
- 'Full theme-adaptive chrome — data colors (Imprint green #009E73 with alpha ramp)
28+
identical across both renders, only chrome (background, ink, grid) flips'
29+
- 'Thoughtful PolarAxis configuration: January at 12 o''clock, clockwise month ordering
30+
matching calendar convention'
31+
- Realistic, neutral monthly-rainfall data (33-95mm) with a plausible wet-winter/dry-summer
32+
temperate-coastal cycle
33+
- Clean KISS script, explicit font sizes throughout, deterministic via Random.seed!(42)
34+
weaknesses:
35+
- The radial tick labels for the 0mm and 20mm rings sit directly on top of the trough
36+
(Jul) wedge's colored fill rather than in clear whitespace, because that wedge
37+
itself extends past 20mm — this partially contradicts the code comment's stated
38+
intent to route labels through a gap. Text stays readable but contrast is reduced
39+
versus the plain background; consider nudging rtickangle further into true whitespace
40+
or skipping/repositioning the innermost 1-2 tick labels.
41+
- Still fundamentally a single-hue radial chart — the alpha ramp and peak/trough
42+
outlines add real hierarchy, but there is room for further polish (e.g., a subtle
43+
secondary visual cue) before this reaches top-tier Design Excellence.
44+
image_description: |-
45+
Light render (plot-light.png):
46+
Background: Warm off-white, consistent with #FAF8F1 — not pure white, not dark.
47+
Chrome: Title "Monthly Rainfall · rose-basic · julia · makie · anyplot.ai" in dark ink, comfortably sized and centered above the "Jan" label. 12 month labels (Jan-Dec) ring the outer edge clockwise from 12 o'clock, all clearly legible in dark gray/ink. Radial gridlines at 0/20/40/60/80/100 mm render as subtle light-gray circles. "mm"-suffixed radial tick labels are routed along the Jul/Aug angular gap; the 40/60/80/100 mm labels land cleanly in whitespace, but the 0 mm and 20 mm labels overlap the trough (Jul) wedge's own fill since that wedge extends past 20mm.
48+
Data: 12 equal-angle wedges filled in Imprint brand green (#009E73) with per-wedge alpha ramped from ~0.55 (driest month, Jul) to ~1.0 (wettest month, Dec) — radius proportional to rainfall value. The Dec (peak) and Jul (trough) wedges carry an additional dark outline stroke as an explicit callout, giving the chart a clear visual focal point on the wet/dry extremes.
49+
Legibility verdict: PASS (title, axis labels, and tick labels all readable against the light background; the 0mm/20mm tick labels sit on wedge fill rather than plain background, which is a minor contrast reduction but not a failure — text remains legible).
50+
51+
Dark render (plot-dark.png):
52+
Background: Warm near-black, consistent with #1A1A17 — not pure black, not light.
53+
Chrome: Same layout with chrome flipped — title and month labels in light ink/off-white, radial tick labels in light gray, gridlines in low-opacity light gray. No dark-on-dark failures; all chrome text reads clearly against the near-black surface.
54+
Data: Identical Imprint green (#009E73) wedges with the same alpha ramp and peak/trough outline treatment (now in a light/white stroke instead of dark) — confirms data colors are unchanged between themes, only chrome adapted.
55+
Legibility verdict: PASS (all text readable against the dark background; same minor 0mm/20mm tick-label-over-wedge-fill placement as the light render, but legible in both cases).
56+
criteria_checklist:
57+
visual_quality:
58+
score: 28
59+
max: 30
60+
items:
61+
- id: VQ-01
62+
name: Text Legibility
63+
score: 7
64+
max: 8
65+
passed: true
66+
comment: rticklabelsize bumped to 15 (from 12), all text explicitly sized
67+
and readable in both themes; minor contrast dip where 0mm/20mm tick labels
68+
sit on wedge fill
69+
- id: VQ-02
70+
name: No Overlap
71+
score: 5
72+
max: 6
73+
passed: true
74+
comment: 0mm and 20mm radial tick labels overlap the trough wedge's fill instead
75+
of clean whitespace; no text-on-text collisions
76+
- id: VQ-03
77+
name: Element Visibility
78+
score: 6
79+
max: 6
80+
passed: true
81+
comment: 12 wedges appropriately sized/spaced; alpha ramp keeps every wedge
82+
distinguishable
83+
- id: VQ-04
84+
name: Color Accessibility
85+
score: 2
86+
max: 2
87+
passed: true
88+
comment: High contrast, no red-green reliance, single-hue ramp is CVD-safe
89+
- id: VQ-05
90+
name: Layout & Canvas
91+
score: 4
92+
max: 4
93+
passed: true
94+
comment: Rose fills the square 2400x2400 canvas with balanced margins, nothing
95+
clipped, canvas gate passed
96+
- id: VQ-06
97+
name: Axis Labels & Title
98+
score: 2
99+
max: 2
100+
passed: true
101+
comment: Radial ticks carry explicit 'mm' units, angular axis self-describing
102+
via month labels
103+
- id: VQ-07
104+
name: Palette Compliance
105+
score: 2
106+
max: 2
107+
passed: true
108+
comment: 'First series #009E73 identical across themes, backgrounds theme-correct
109+
(#FAF8F1 / #1A1A17)'
110+
design_excellence:
111+
score: 16
112+
max: 20
113+
items:
114+
- id: DE-01
115+
name: Aesthetic Sophistication
116+
score: 6
117+
max: 8
118+
passed: true
119+
comment: Alpha ramp by value plus peak/trough outline callouts add real polish
120+
over the prior flat single-color fill
121+
- id: DE-02
122+
name: Visual Refinement
123+
score: 5
124+
max: 6
125+
passed: true
126+
comment: Subtle low-opacity grid, single clean spine, generous whitespace
127+
- id: DE-03
128+
name: Data Storytelling
129+
score: 5
130+
max: 6
131+
passed: true
132+
comment: Peak (Dec) and trough (Jul) wedges are now explicitly outlined, giving
133+
the seasonal story an immediate visual anchor
134+
spec_compliance:
135+
score: 15
136+
max: 15
137+
items:
138+
- id: SC-01
139+
name: Plot Type
140+
score: 5
141+
max: 5
142+
passed: true
143+
comment: 'Correct rose/coxcomb chart: equal-angle wedges, radius-encoded values'
144+
- id: SC-02
145+
name: Required Features
146+
score: 4
147+
max: 4
148+
passed: true
149+
comment: Radius (not area) proportional to value, natural circular ordering,
150+
consistent color w/ varying saturation, 12 o'clock start, radial gridlines
151+
- id: SC-03
152+
name: Data Mapping
153+
score: 3
154+
max: 3
155+
passed: true
156+
comment: Category to angle, value to radius correct, all 12 months visible
157+
- id: SC-04
158+
name: Title & Legend
159+
score: 3
160+
max: 3
161+
passed: true
162+
comment: Title format correct; single series, no legend needed
163+
data_quality:
164+
score: 14
165+
max: 15
166+
items:
167+
- id: DQ-01
168+
name: Feature Coverage
169+
score: 5
170+
max: 6
171+
passed: true
172+
comment: Full seasonal cycle (33-95mm) with clear high/low, variation is fairly
173+
smooth
174+
- id: DQ-02
175+
name: Realistic Context
176+
score: 5
177+
max: 5
178+
passed: true
179+
comment: Plausible, neutral temperate-coastal-city rainfall scenario
180+
- id: DQ-03
181+
name: Appropriate Scale
182+
score: 4
183+
max: 4
184+
passed: true
185+
comment: Values and seasonality consistent with real temperate coastal climates
186+
code_quality:
187+
score: 10
188+
max: 10
189+
items:
190+
- id: CQ-01
191+
name: KISS Structure
192+
score: 3
193+
max: 3
194+
passed: true
195+
comment: Imports -> data -> plot -> save, only a simple per-wedge loop
196+
- id: CQ-02
197+
name: Reproducibility
198+
score: 2
199+
max: 2
200+
passed: true
201+
comment: Random.seed!(42)
202+
- id: CQ-03
203+
name: Clean Imports
204+
score: 2
205+
max: 2
206+
passed: true
207+
comment: CairoMakie, Colors, Random all used
208+
- id: CQ-04
209+
name: Code Elegance
210+
score: 2
211+
max: 2
212+
passed: true
213+
comment: Appropriately complex, comments justify band! over poly! and the
214+
alpha/outline choices
215+
- id: CQ-05
216+
name: Output & API
217+
score: 1
218+
max: 1
219+
passed: true
220+
comment: Saves plot-$(THEME).png via current API
221+
library_mastery:
222+
score: 8
223+
max: 10
224+
items:
225+
- id: LM-01
226+
name: Idiomatic Usage
227+
score: 4
228+
max: 5
229+
passed: true
230+
comment: PolarAxis with correct theta_0/direction/rtick configuration
231+
- id: LM-02
232+
name: Distinctive Features
233+
score: 4
234+
max: 5
235+
passed: true
236+
comment: band! sampled over 40 points per wedge exploits PolarAxis's per-vertex
237+
transform for true curved arcs — a Makie-specific technique
238+
verdict: APPROVED
239+
impl_tags:
240+
dependencies: []
241+
techniques:
242+
- polar-projection
243+
- manual-ticks
244+
patterns:
245+
- data-generation
246+
- iteration-over-groups
247+
dataprep: []
248+
styling:
249+
- alpha-blending
250+
- edge-highlighting
251+
- grid-styling

0 commit comments

Comments
 (0)