Skip to content

Commit fbc44ff

Browse files
feat(makie): implement errorbar-basic (#9527)
## Implementation: `errorbar-basic` - julia/makie Implements the **julia/makie** version of `errorbar-basic`. **File:** `plots/errorbar-basic/implementations/julia/makie.jl` **Parent Issue:** #973 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/28473971049)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: claude[bot] <41898282+claude[bot]@users.noreply.github.com> Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com>
1 parent aeb08a7 commit fbc44ff

2 files changed

Lines changed: 364 additions & 0 deletions

File tree

Lines changed: 105 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,105 @@
1+
# anyplot.ai
2+
# errorbar-basic: Basic Error Bar Plot
3+
# Library: makie 0.21.9 | Julia 1.11.9
4+
# Quality: 88/100 | Created: 2026-06-30
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 INK_MUTED = THEME == "light" ? colorant"#6B6A63" : colorant"#A8A79F"
18+
const IMPRINT_PALETTE = [
19+
colorant"#009E73", # 1 — first categorical series (Imprint brand green)
20+
colorant"#C475FD", # 2 — lavender
21+
colorant"#4467A3", # 3 — blue
22+
colorant"#BD8233", # 4 — ochre
23+
colorant"#AE3030", # 5 — matte red
24+
colorant"#2ABCCD", # 6 — cyan
25+
colorant"#954477", # 7 — rose
26+
colorant"#99B314", # 8 — lime
27+
]
28+
29+
# Data: Mean seedling height (cm) under 6 light intensity levels
30+
# Standard deviation from 20 replicate seedlings per condition
31+
light_levels = ["50 lux", "100 lux", "200 lux", "400 lux", "800 lux", "1600 lux"]
32+
mean_height = [1.2, 2.8, 4.5, 6.1, 7.3, 7.8]
33+
std_height = [0.35, 0.42, 0.51, 0.68, 0.72, 0.85]
34+
n = length(light_levels)
35+
x_pos = collect(1:n)
36+
37+
# Plot
38+
fig = Figure(
39+
size = (1600, 900),
40+
fontsize = 14,
41+
backgroundcolor = PAGE_BG,
42+
)
43+
44+
ax = Axis(
45+
fig[1, 1];
46+
title = "errorbar-basic · julia · makie · anyplot.ai",
47+
titlesize = 20,
48+
titlecolor = INK,
49+
xlabel = "Light Intensity",
50+
ylabel = "Mean Seedling Height (cm)",
51+
xlabelsize = 14,
52+
ylabelsize = 14,
53+
xlabelcolor = INK,
54+
ylabelcolor = INK,
55+
xticklabelcolor = INK_SOFT,
56+
yticklabelcolor = INK_SOFT,
57+
xticklabelsize = 12,
58+
yticklabelsize = 12,
59+
xtickcolor = INK_SOFT,
60+
ytickcolor = INK_SOFT,
61+
backgroundcolor = PAGE_BG,
62+
topspinevisible = false,
63+
rightspinevisible = false,
64+
leftspinecolor = INK_SOFT,
65+
bottomspinecolor = INK_SOFT,
66+
xgridvisible = false,
67+
ygridvisible = false,
68+
yminorgridvisible = false,
69+
xticks = (x_pos, light_levels),
70+
)
71+
72+
# Highlight the growth saturation region (800–1600 lux = x positions 5–6)
73+
c = IMPRINT_PALETTE[1]
74+
vspan!(ax, [4.5], [6.5];
75+
color = RGBAf(Float32(c.r), Float32(c.g), Float32(c.b), 0.08f0),
76+
)
77+
78+
errorbars!(ax, x_pos, mean_height, std_height;
79+
color = IMPRINT_PALETTE[1],
80+
linewidth = 2.5,
81+
whiskerwidth = 12,
82+
)
83+
84+
lines!(ax, x_pos, mean_height;
85+
color = IMPRINT_PALETTE[1],
86+
linewidth = 2.0,
87+
)
88+
89+
scatter!(ax, x_pos, mean_height;
90+
color = IMPRINT_PALETTE[1],
91+
markersize = 14,
92+
strokewidth = 1.5,
93+
strokecolor = PAGE_BG,
94+
)
95+
96+
# Annotate the saturation plateau to guide the reader to the key insight
97+
text!(ax, 5.5, 8.4;
98+
text = "growth plateau",
99+
color = INK_MUTED,
100+
fontsize = 12,
101+
align = (:center, :bottom),
102+
)
103+
104+
# Save
105+
save("plot-$(THEME).png", fig; px_per_unit = 2)
Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,259 @@
1+
library: makie
2+
language: julia
3+
specification_id: errorbar-basic
4+
created: '2026-06-30T20:44:21Z'
5+
updated: '2026-06-30T21:12:36Z'
6+
generated_by: claude-sonnet
7+
workflow_run: 28473971049
8+
issue: 973
9+
language_version: 1.11.9
10+
library_version: 0.21.9
11+
preview_url_light: https://storage.googleapis.com/anyplot-images/plots/errorbar-basic/julia/makie/plot-light.png
12+
preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/errorbar-basic/julia/makie/plot-dark.png
13+
preview_html_light: null
14+
preview_html_dark: null
15+
quality_score: 88
16+
review:
17+
strengths:
18+
- Clean layer composition (errorbars! + lines! + scatter!) showcasing Makie compositional
19+
API
20+
- 'Excellent theme adaptation: all chrome elements use correct INK/INK_SOFT tokens
21+
for both light and dark renders'
22+
- Error bars have visible caps (whiskerwidth=12) meeting spec requirement
23+
- Data storytelling via vspan highlight + growth plateau annotation adds narrative
24+
value
25+
- Idiomatic CairoMakie code throughout — native recipes, RGBAf, colorant strings,
26+
Figure/Axis API
27+
weaknesses:
28+
- vspan! highlight alpha is 0.08 — barely perceptible in both renders; increase
29+
to 0.12-0.15 for the subtle plateau region to actually register visually
30+
- growth plateau annotation uses fontsize=12 with INK_MUTED color — readable but
31+
quite small; consider fontsize=13 for better visibility at mobile scale
32+
- Grid lines appear visible in renders at y=2.5, 5.0, 7.5 despite xgridvisible=false
33+
and ygridvisible=false; if unintentional, verify attribute names; if intentional,
34+
add explicit ygridcolor styling using INK token at 0.15 alpha per the Makie guide
35+
skeleton
36+
image_description: |-
37+
Light render (plot-light.png):
38+
Background: Warm off-white (#FAF8F1) — correct theme surface
39+
Chrome: Title "errorbar-basic · julia · makie · anyplot.ai" in bold dark (#1A1A17) text, centered; Y-axis label "Mean Seedling Height (cm)" rotated in dark text; X-axis label "Light Intensity" in dark text; tick labels ("50 lux" … "1600 lux", 2.5/5.0/7.5) in INK_SOFT dark gray — all clearly readable. Faint horizontal grid lines visible at y=2.5, 5.0, 7.5 (despite xgridvisible=false, ygridvisible=false in code). Top/right spines absent; left/bottom spines in INK_SOFT. "growth plateau" annotation visible near top-center of right section in INK_MUTED (tertiary gray) at fontsize=12 — readable but subtle. Very faint vspan region highlight on far right (0.08 alpha, barely perceptible).
40+
Data: Single series in #009E73 brand green — errorbars with horizontal whisker caps, smooth line through 6 data points, circular scatter markers with PAGE_BG stroke. Ascending growth curve flattening at high light levels.
41+
Legibility verdict: PASS — all text elements clearly readable against light background; no light-on-light issues.
42+
43+
Dark render (plot-dark.png):
44+
Background: Warm near-black (#1A1A17) — correct dark theme surface
45+
Chrome: Title in cream (#F0EFE8) text clearly readable; Y-axis and X-axis labels in cream text; tick labels in INK_SOFT (#B8B7B0 soft gray) — all visible against dark background. Faint horizontal grid lines similarly visible. "growth plateau" annotation in INK_MUTED (#A8A79F, ~8:1 contrast ratio) — readable. No dark-on-dark text issues found.
46+
Data: Colors identical to light render — same #009E73 green for errorbars, line, and scatter markers. Data colors unchanged across themes (only chrome flipped). Brand green #009E73 clearly visible and well-contrasted against dark background.
47+
Legibility verdict: PASS — all text readable against dark background; no dark-on-dark failures detected.
48+
criteria_checklist:
49+
visual_quality:
50+
score: 29
51+
max: 30
52+
items:
53+
- id: VQ-01
54+
name: Text Legibility
55+
score: 7
56+
max: 8
57+
passed: true
58+
comment: 'All font sizes explicitly set via titlesize=20, xlabelsize=14, ylabelsize=14,
59+
xticklabelsize=12, yticklabelsize=12. Both themes fully readable. Minor:
60+
annotation fontsize=12 in INK_MUTED is slightly subtle at mobile scale.'
61+
- id: VQ-02
62+
name: No Overlap
63+
score: 6
64+
max: 6
65+
passed: true
66+
comment: 6 well-spaced data points, no text collisions.
67+
- id: VQ-03
68+
name: Element Visibility
69+
score: 6
70+
max: 6
71+
passed: true
72+
comment: markersize=14 and whiskerwidth=12 appropriate for 6-point sparse
73+
data. Error bars with caps clearly visible.
74+
- id: VQ-04
75+
name: Color Accessibility
76+
score: 2
77+
max: 2
78+
passed: true
79+
comment: 'Single series in #009E73, excellent contrast on both backgrounds,
80+
no CVD concerns.'
81+
- id: VQ-05
82+
name: Layout & Canvas
83+
score: 4
84+
max: 4
85+
passed: true
86+
comment: Canvas gate passed (3200x1800). Good whitespace. L-shaped frame.
87+
No clipping.
88+
- id: VQ-06
89+
name: Axis Labels & Title
90+
score: 2
91+
max: 2
92+
passed: true
93+
comment: 'Title correct format. Y-axis: ''Mean Seedling Height (cm)'' with
94+
units. X-axis: ''Light Intensity'' descriptive.'
95+
- id: VQ-07
96+
name: Palette Compliance
97+
score: 2
98+
max: 2
99+
passed: true
100+
comment: 'First series IMPRINT_PALETTE[1]=#009E73. Backgrounds #FAF8F1 light
101+
/ #1A1A17 dark. All chrome theme-adaptive. Data colors identical across
102+
both renders.'
103+
design_excellence:
104+
score: 12
105+
max: 20
106+
items:
107+
- id: DE-01
108+
name: Aesthetic Sophistication
109+
score: 5
110+
max: 8
111+
passed: true
112+
comment: Layered composition (errorbars+line+scatter) with Imprint palette
113+
shows intentional design above library defaults. vspan+annotation add narrative.
114+
vspan at 0.08 alpha is barely perceptible which weakens the visual impact
115+
somewhat.
116+
- id: DE-02
117+
name: Visual Refinement
118+
score: 4
119+
max: 6
120+
passed: true
121+
comment: L-shaped spine frame, INK_SOFT colors on remaining spines, scatter
122+
marker stroke (strokewidth=1.5, strokecolor=PAGE_BG) for definition. Horizontal
123+
grid lines appear in render despite ygridvisible=false.
124+
- id: DE-03
125+
name: Data Storytelling
126+
score: 3
127+
max: 6
128+
passed: true
129+
comment: Growth plateau story communicated via annotation text and vspan.
130+
But vspan at 0.08 alpha barely registers; annotation carries most of the
131+
storytelling load.
132+
spec_compliance:
133+
score: 15
134+
max: 15
135+
items:
136+
- id: SC-01
137+
name: Plot Type
138+
score: 5
139+
max: 5
140+
passed: true
141+
comment: Correct error bar plot with visible caps (whiskerwidth=12). errorbars!
142+
primitive used.
143+
- id: SC-02
144+
name: Required Features
145+
score: 4
146+
max: 4
147+
passed: true
148+
comment: Error bars with caps, consistent widths, data markers, connected
149+
trend line all present.
150+
- id: SC-03
151+
name: Data Mapping
152+
score: 3
153+
max: 3
154+
passed: true
155+
comment: 'X: light intensity levels (categorical). Y: mean seedling height
156+
(cm). Error: standard deviation. All 6 points shown.'
157+
- id: SC-04
158+
name: Title & Legend
159+
score: 3
160+
max: 3
161+
passed: true
162+
comment: 'Title: ''errorbar-basic · julia · makie · anyplot.ai'' correct format.
163+
Single series, no legend needed.'
164+
data_quality:
165+
score: 15
166+
max: 15
167+
items:
168+
- id: DQ-01
169+
name: Feature Coverage
170+
score: 6
171+
max: 6
172+
passed: true
173+
comment: Error bars, trend line, markers, region highlight, annotation — comprehensive
174+
feature coverage for the error bar plot type.
175+
- id: DQ-02
176+
name: Realistic Context
177+
score: 5
178+
max: 5
179+
passed: true
180+
comment: Seedling height under light intensity experiment — scientifically
181+
plausible and neutral. Values (1.2-7.8 cm), light levels (50-1600 lux),
182+
std devs (0.35-0.85) all realistic.
183+
- id: DQ-03
184+
name: Appropriate Scale
185+
score: 4
186+
max: 4
187+
passed: true
188+
comment: 6 data points within 3-20 spec range. Values and error magnitudes
189+
(~10-15% of mean) consistent with real seedling growth experiments.
190+
code_quality:
191+
score: 10
192+
max: 10
193+
items:
194+
- id: CQ-01
195+
name: KISS Structure
196+
score: 3
197+
max: 3
198+
passed: true
199+
comment: 'Linear script: theme tokens → data → plot → save. No functions or
200+
classes.'
201+
- id: CQ-02
202+
name: Reproducibility
203+
score: 2
204+
max: 2
205+
passed: true
206+
comment: Random.seed!(42) present. Data is hardcoded arrays so deterministic
207+
by construction.
208+
- id: CQ-03
209+
name: Clean Imports
210+
score: 2
211+
max: 2
212+
passed: true
213+
comment: CairoMakie (plotting), Colors (colorant strings), Random (seed) —
214+
all imported and used.
215+
- id: CQ-04
216+
name: Code Elegance
217+
score: 2
218+
max: 2
219+
passed: true
220+
comment: Clean and readable. RGBAf inline construction for vspan color is
221+
slightly verbose but correct. No fake UI.
222+
- id: CQ-05
223+
name: Output & API
224+
score: 1
225+
max: 1
226+
passed: true
227+
comment: Saves as plot-$(THEME).png with px_per_unit=2. Correct output format.
228+
library_mastery:
229+
score: 7
230+
max: 10
231+
items:
232+
- id: LM-01
233+
name: Idiomatic Usage
234+
score: 4
235+
max: 5
236+
passed: true
237+
comment: Multiple Makie recipes composited on one Axis (errorbars!, lines!,
238+
scatter!, vspan!, text!). Proper Figure/Axis API, RGBAf for alpha colors,
239+
colorant strings from Colors.jl — consistently idiomatic.
240+
- id: LM-02
241+
name: Distinctive Features
242+
score: 3
243+
max: 5
244+
passed: true
245+
comment: errorbars! with whiskerwidth (Makie-specific recipe), vspan! for
246+
region highlighting (Makie-specific), layer composition of 5 plot primitives
247+
on one Axis showcasing Makie's composable design.
248+
verdict: APPROVED
249+
impl_tags:
250+
dependencies: []
251+
techniques:
252+
- annotations
253+
- layer-composition
254+
patterns:
255+
- data-generation
256+
dataprep: []
257+
styling:
258+
- alpha-blending
259+
- edge-highlighting

0 commit comments

Comments
 (0)