From cd5d6dddd14e4a6928f6c5e08925a4835d2e95b5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 01:08:45 +0000 Subject: [PATCH 1/3] feat(makie): implement horizon-basic --- .../implementations/julia/makie.jl | 126 ++++++++++++++++++ 1 file changed, 126 insertions(+) create mode 100644 plots/horizon-basic/implementations/julia/makie.jl diff --git a/plots/horizon-basic/implementations/julia/makie.jl b/plots/horizon-basic/implementations/julia/makie.jl new file mode 100644 index 0000000000..d9974d9916 --- /dev/null +++ b/plots/horizon-basic/implementations/julia/makie.jl @@ -0,0 +1,126 @@ +# anyplot.ai +# horizon-basic: Horizon Chart +# Library: Makie.jl 0.21 | Julia 1.11 +# Quality: pending | Created: 2026-08-18 + +using CairoMakie +using Colors +using ColorSchemes +using Random +using Statistics + +Random.seed!(42) + +# --- Theme tokens ------------------------------------------------------- +THEME = get(ENV, "ANYPLOT_THEME", "light") +PAGE_BG = THEME == "light" ? colorant"#FAF8F1" : colorant"#1A1A17" +INK = THEME == "light" ? colorant"#1A1A17" : colorant"#F0EFE8" +INK_SOFT = THEME == "light" ? colorant"#4A4A44" : colorant"#B8B7B0" + +# Imprint diverging colormap (red -> midpoint -> blue). Horizon bands use its +# two endpoints: blue for positive deviation, red for negative deviation. +midpoint = THEME == "light" ? colorant"#FAF8F1" : colorant"#1A1A17" +ANYPLOT_DIV = cgrad([colorant"#AE3030", midpoint, colorant"#4467A3"]) +POS_COLOR = get(ANYPLOT_DIV, 1.0) +NEG_COLOR = get(ANYPLOT_DIV, 0.0) + +# --- Data ----------------------------------------------------------------- +# Simulated CPU-load deviation (percentage points from a 50% baseline) for a +# small fleet of servers, sampled hourly. +servers = ["web-1", "web-2", "web-3", "api-1", "api-2", "api-3", + "db-1", "db-2", "cache-1", "cache-2", "queue-1", "lb-1"] +n_series = length(servers) +n_points = 200 +hours = collect(0:(n_points - 1)) + +deviations = Matrix{Float64}(undef, n_points, n_series) +for j in 1:n_series + scale = 5.0 + 4.0 * rand() + walk = cumsum(randn(n_points) .* scale .* 0.18) + walk .-= mean(walk) + deviations[:, j] = clamp.(walk, -45.0, 45.0) +end + +n_bands = 3 +max_abs = maximum(abs.(deviations)) +band_step = max_abs / n_bands +band_alphas = [0.35, 0.65, 1.0] + +row_pitch = 1.0 +row_h = 0.78 + +# --- Plot ------------------------------------------------------------------- +fig = Figure( + resolution = (1600, 900), + fontsize = 14, + backgroundcolor = PAGE_BG, +) + +Label( + fig[1, 1], + "Server CPU-load deviation from baseline · 3 intensity bands per polarity — darker = larger swing"; + fontsize = 13, + color = INK_SOFT, + halign = :left, + tellwidth = false, +) + +ax = Axis( + fig[2, 1]; + title = "horizon-basic · julia · makie · anyplot.ai", + titlesize = 20, + titlecolor = INK, + xlabel = "Time (hours)", + xlabelcolor = INK, + xlabelsize = 14, + xticklabelcolor = INK_SOFT, + xticklabelsize = 12, + yticklabelcolor = INK_SOFT, + yticklabelsize = 12, + backgroundcolor = PAGE_BG, + topspinevisible = false, + rightspinevisible = false, + leftspinevisible = false, + bottomspinecolor = INK_SOFT, + xgridvisible = false, + ygridvisible = false, + yticksvisible = false, + xtickcolor = INK_SOFT, +) + +for i in 1:n_series + row_index = n_series - i + 1 + row_base = (row_index - 1) * row_pitch + v = deviations[:, i] + + for b in 1:n_bands + lower = (b - 1) * band_step + upper = b * band_step + + pos_frac = (clamp.(v, lower, upper) .- lower) ./ band_step + y_top = row_base .+ pos_frac .* row_h + y_bottom = fill(row_base, n_points) + band!(ax, hours, y_bottom, y_top; color = (POS_COLOR, band_alphas[b])) + + neg_frac = (clamp.(.-v, lower, upper) .- lower) ./ band_step + y_bottom2 = row_base .+ row_h .- neg_frac .* row_h + y_top2 = fill(row_base + row_h, n_points) + band!(ax, hours, y_bottom2, y_top2; color = (NEG_COLOR, band_alphas[b])) + end +end + +for i in 0:n_series + y = i * row_pitch + hlines!(ax, [y]; color = RGBAf(INK.r, INK.g, INK.b, 0.12), linewidth = 1) +end + +row_centers = [(n_series - i) * row_pitch + row_h / 2 for i in 1:n_series] +ax.yticks = (row_centers, servers) + +xlims!(ax, 0, n_points - 1) +ylims!(ax, 0, n_series * row_pitch) + +rowsize!(fig.layout, 1, Auto(false, 0.05)) + +# --- Save ------------------------------------------------------------------- +save("plot-$(THEME).png", fig; px_per_unit = 2) From 769d1047b5e748ceeca87924b16e443420971956 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 01:08:54 +0000 Subject: [PATCH 2/3] chore(makie): add metadata for horizon-basic --- plots/horizon-basic/metadata/julia/makie.yaml | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) create mode 100644 plots/horizon-basic/metadata/julia/makie.yaml diff --git a/plots/horizon-basic/metadata/julia/makie.yaml b/plots/horizon-basic/metadata/julia/makie.yaml new file mode 100644 index 0000000000..4b5da8831f --- /dev/null +++ b/plots/horizon-basic/metadata/julia/makie.yaml @@ -0,0 +1,21 @@ +# Per-library metadata for makie implementation of horizon-basic +# Auto-generated by impl-generate.yml + +library: makie +language: julia +specification_id: horizon-basic +created: '2026-08-18T01:08:53Z' +updated: '2026-08-18T01:08:53Z' +generated_by: claude-sonnet +workflow_run: 32086405520 +issue: 1877 +language_version: 1.11.9 +library_version: 0.21.9 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/horizon-basic/julia/makie/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/horizon-basic/julia/makie/plot-dark.png +preview_html_light: null +preview_html_dark: null +quality_score: null +review: + strengths: [] + weaknesses: [] From b040824e9d7ad7995055258f1ec71d44f4e1cff5 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Tue, 18 Aug 2026 01:15:08 +0000 Subject: [PATCH 3/3] chore(makie): update quality score 89 and review feedback for horizon-basic --- .../implementations/julia/makie.jl | 4 +- plots/horizon-basic/metadata/julia/makie.yaml | 257 +++++++++++++++++- 2 files changed, 252 insertions(+), 9 deletions(-) diff --git a/plots/horizon-basic/implementations/julia/makie.jl b/plots/horizon-basic/implementations/julia/makie.jl index d9974d9916..80171493a0 100644 --- a/plots/horizon-basic/implementations/julia/makie.jl +++ b/plots/horizon-basic/implementations/julia/makie.jl @@ -1,7 +1,7 @@ # anyplot.ai # horizon-basic: Horizon Chart -# Library: Makie.jl 0.21 | Julia 1.11 -# Quality: pending | Created: 2026-08-18 +# Library: makie 0.21.9 | Julia 1.11.9 +# Quality: 89/100 | Created: 2026-08-18 using CairoMakie using Colors diff --git a/plots/horizon-basic/metadata/julia/makie.yaml b/plots/horizon-basic/metadata/julia/makie.yaml index 4b5da8831f..80aec1c432 100644 --- a/plots/horizon-basic/metadata/julia/makie.yaml +++ b/plots/horizon-basic/metadata/julia/makie.yaml @@ -1,11 +1,8 @@ -# Per-library metadata for makie implementation of horizon-basic -# Auto-generated by impl-generate.yml - library: makie language: julia specification_id: horizon-basic created: '2026-08-18T01:08:53Z' -updated: '2026-08-18T01:08:53Z' +updated: '2026-08-18T01:15:08Z' generated_by: claude-sonnet workflow_run: 32086405520 issue: 1877 @@ -15,7 +12,253 @@ preview_url_light: https://storage.googleapis.com/anyplot-images/plots/horizon-b preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/horizon-basic/julia/makie/plot-dark.png preview_html_light: null preview_html_dark: null -quality_score: null +quality_score: 89 review: - strengths: [] - weaknesses: [] + strengths: + - Excellent horizon-chart folding technique via band! with 3 alpha-graded intensity + bands per polarity (0.35/0.65/1.0), cleanly compacting 12 servers' CPU-load deviation + into a compact, readable panel. + - 'Correct, theme-adaptive use of the Imprint diverging colormap endpoints (blue + #4467A3 / red #AE3030) for positive/negative deviation, matching the spec''s suggested + mirrored polarity coloring, with data colors identical across light and dark themes.' + - 'Clean, minimal chrome: all spines removed except a soft bottom line, no grid, + subtle theme-adaptive row dividers (alpha 0.12), generous whitespace, and explicit + font sizing throughout (title/subtitle/axis/tick all set).' + - Realistic, neutral server-monitoring dataset with per-server volatility variation + (scale = 5-9), giving genuinely different visual behavior per row rather than + repeating the same shape — good feature coverage of both polarities and all three + intensity levels. + - Idiomatic Makie usage of the Figure grid layout system (Label + Axis across fig[1,1]/fig[2,1] + with rowsize!) for a custom two-row composition — distinctive to Makie's layout + model. + weaknesses: + - No legend or annotation clarifies which color represents positive vs. negative + deviation (blue = above baseline, red = below baseline) — a viewer unfamiliar + with horizon-chart conventions cannot decode polarity from the chart alone. The + subtitle only explains 'darker = larger swing', not the color-to-polarity mapping. + Add a compact 2-swatch legend (or extend the subtitle) stating the mapping explicitly. + - The intensity bands communicate only relative magnitude ('darker = larger swing') + with no indication of the underlying scale (percentage points per band) — consider + a small band-scale legend or annotation so the shading is quantitatively interpretable. + - 'Layout order is slightly unconventional: the small gray caption (Label in fig[1,1]) + renders above the bold mandated title (Axis title in fig[2,1]) rather than below + it as a typical subtitle would — consider swapping the visual hierarchy so the + mandated title reads first.' + image_description: |- + Light render (plot-light.png): + Background: Warm off-white, consistent with #FAF8F1 — not pure white. + Chrome: Small gray caption at top-left ("Server CPU-load deviation from baseline · 3 intensity bands per polarity — darker = larger swing") in soft ink; bold dark title "horizon-basic · julia · makie · anyplot.ai" centered above the plot area; 12 server-name row labels (web-1/2/3, api-1/2/3, db-1/2, cache-1/2, queue-1, lb-1) in soft gray on the left; x-axis "Time (hours)" with tick labels 0/50/100/150 in soft gray. All text renders dark-on-light and is clearly legible. + Data: Each row folds a single time series into stacked, alpha-graded bands — blue (#4467A3, the Imprint diverging colormap's positive endpoint) for above-baseline deviation, red (#AE3030, the negative endpoint) for below-baseline, with 3 increasing-alpha bands (0.35/0.65/1.0) per polarity so darker = larger swing. Thin light-gray horizontal dividers separate rows. No legend explains the color-to-polarity mapping. + Legibility verdict: PASS — all chrome text is clearly readable against the light background; no dark-on-dark or light-on-light issues. + + Dark render (plot-dark.png): + Background: Warm near-black, consistent with #1A1A17 — not pure black. + Chrome: Same caption and title, now rendered in light gray / off-white; row labels and axis tick labels in light gray; all text is clearly legible against the dark background — no dark-on-dark failures observed. + Data: Identical blue (#4467A3) and red (#AE3030) band colors and alpha levels as the light render — confirms the diverging colormap endpoints are theme-independent as required; only the chrome (background, text, row-divider color) flips between themes. + Legibility verdict: PASS — all text remains readable in the dark theme, and the data colors are confirmed identical to the light render. + criteria_checklist: + visual_quality: + score: 29 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: All font sizes explicitly set (titlesize=20, xlabelsize=14, tick + sizes=12), readable in both themes; 12 dense rows make the 12pt row/tick + labels tight for mobile legibility. + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No overlap between row labels, ticks, title, or data bands. + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: Band fills are clearly visible and well-adapted to 200 points x 12 + series. + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Blue/red diverging pair gives strong hue+lightness contrast, not + red-green-only. + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: Chart fills the vast majority of the canvas with balanced margins; + nothing cut off. + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Title format correct; x-axis 'Time (hours)' has units; y-axis uses + descriptive server names. + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: Band colors are the Imprint imprint_div diverging colormap's endpoints + (blue/red), a legitimate fit for genuinely diverging deviation data; theme-adaptive + chrome and PAGE_BG are correct in both renders; data colors identical across + themes. + design_excellence: + score: 15 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 6 + max: 8 + passed: true + comment: Thoughtful alpha-graded diverging color mapping and minimal typography + hierarchy, clearly above library defaults. + - id: DE-02 + name: Visual Refinement + score: 5 + max: 6 + passed: true + comment: Spines removed, no grid, subtle theme-adaptive row dividers, generous + whitespace. + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: true + comment: Color-intensity hierarchy lets a viewer spot anomalous/volatile servers + at a glance, though no explicit annotation calls one out. + spec_compliance: + score: 13 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: 'Correct horizon chart: many series folded into color-coded bands.' + - id: SC-02 + name: Required Features + score: 3 + max: 4 + passed: true + comment: 3 bands, mirrored polarity coloring, and a meaningful (zero) baseline + are all present, but the polarity mapping is never communicated to the viewer. + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: Time on x, series as rows, deviation folded correctly; all data visible. + - id: SC-04 + name: Title & Legend + score: 2 + max: 3 + passed: true + comment: Title format is exactly correct; no legend exists to confirm color/polarity + mapping. + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: Both polarities and all 3 intensity levels shown; per-server volatility + varies so rows are visually distinct. + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Neutral, realistic server-fleet CPU monitoring scenario. + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Deviation range (±45pp around a 50% baseline) is plausible for CPU + load monitoring. + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: Sequential imports -> data -> plot -> save, no functions/classes. + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: Random.seed!(42) set. + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: All imports (CairoMakie, Colors, ColorSchemes, Random, Statistics) + are used. + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Nested band/polarity loops are appropriate complexity for a horizon + chart; no fake functionality. + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves plot-$(THEME).png with current save/px_per_unit API. + library_mastery: + score: 7 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 4 + max: 5 + passed: true + comment: Idiomatic use of band!, hlines!, Axis, and the Figure grid layout + system. + - id: LM-02 + name: Distinctive Features + score: 3 + max: 5 + passed: true + comment: band! fill-between plus Figure grid layout (Label + rowsize!) for + a custom two-row composition are distinctive to Makie. + verdict: REJECTED +impl_tags: + dependencies: [] + techniques: + - manual-ticks + - layer-composition + patterns: + - data-generation + - iteration-over-groups + - matrix-construction + dataprep: + - cumulative-sum + - normalization + - time-series + styling: + - alpha-blending + - minimal-chrome