diff --git a/plots/count-basic/implementations/julia/makie.jl b/plots/count-basic/implementations/julia/makie.jl new file mode 100644 index 0000000000..7b3805815f --- /dev/null +++ b/plots/count-basic/implementations/julia/makie.jl @@ -0,0 +1,103 @@ +# anyplot.ai +# count-basic: Basic Count Plot +# Library: makie 0.21.9 | Julia 1.11.9 +# Quality: 87/100 | Created: 2026-08-11 + +using CairoMakie +using Colors +using Random + +Random.seed!(42) + +# --- Theme tokens ----------------------------------------------------------- +const THEME = get(ENV, "ANYPLOT_THEME", "light") +const PAGE_BG = THEME == "light" ? colorant"#FAF8F1" : colorant"#1A1A17" +const INK = THEME == "light" ? colorant"#1A1A17" : colorant"#F0EFE8" +const INK_SOFT = THEME == "light" ? colorant"#4A4A44" : colorant"#B8B7B0" +const BRAND = colorant"#009E73" # Imprint palette position 1 — ALWAYS first series + +# --- Data --------------------------------------------------------------- +# Raw survey responses (one row per respondent) — a count plot tallies these +# directly, unlike a bar chart which needs pre-aggregated values. +device_pool = vcat( + fill("Smartphone", 342), + fill("Laptop", 268), + fill("Tablet", 145), + fill("Desktop", 98), + fill("Smartwatch", 61), + fill("E-reader", 24), +) +responses = shuffle(device_pool) + +counts_by_category = Dict{String,Int}() +for r in responses + counts_by_category[r] = get(counts_by_category, r, 0) + 1 +end + +categories = collect(keys(counts_by_category)) +tallies = [counts_by_category[c] for c in categories] +order = sortperm(tallies; rev = true) +categories = categories[order] +tallies = tallies[order] + +n = length(categories) +total_responses = sum(tallies) +leading_share = round(Int, 100 * tallies[1] / total_responses) +title_str = "count-basic · julia · makie · anyplot.ai" + +# --- Plot ----------------------------------------------------------------- +fig = Figure( + size = (1600, 900), + fontsize = 14, + backgroundcolor = PAGE_BG, +) + +ax = Axis( + fig[1, 1]; + title = title_str, + titlesize = 27, + titlecolor = INK, + xlabel = "Primary Device Used for Survey", + ylabel = "Number of Respondents", + xlabelcolor = INK, + ylabelcolor = INK, + xlabelsize = 14, + ylabelsize = 14, + xticks = (1:n, categories), + xticklabelsize = 12, + yticklabelsize = 12, + xticklabelcolor = INK_SOFT, + yticklabelcolor = INK_SOFT, + xtickcolor = INK_SOFT, + ytickcolor = INK_SOFT, + backgroundcolor = PAGE_BG, + topspinevisible = false, + rightspinevisible = false, + leftspinecolor = INK_SOFT, + bottomspinecolor = INK_SOFT, + xgridvisible = false, + ygridcolor = RGBAf(INK.r, INK.g, INK.b, 0.15), +) + +# Leading category gets a subtle ink outline to draw the eye without +# breaking the single brand-green palette rule. +stroke_widths = zeros(Float64, n) +stroke_widths[1] = 3.0 +barplot!(ax, 1:n, tallies; color = BRAND, width = 0.65, + strokewidth = stroke_widths, strokecolor = INK) + +for (i, count) in enumerate(tallies) + if i == 1 + label = "$(count) ($(leading_share)% of responses)" + text!(ax, i, count; text = label, align = (:center, :bottom), + offset = (0, 8), color = INK, fontsize = 16) + else + text!(ax, i, count; text = string(count), align = (:center, :bottom), + offset = (0, 6), color = INK_SOFT, fontsize = 13) + end +end + +ylims!(ax, 0, maximum(tallies) * 1.18) + +# --- Save ------------------------------------------------------------------- +save("plot-$(THEME).png", fig; px_per_unit = 2) diff --git a/plots/count-basic/metadata/julia/makie.yaml b/plots/count-basic/metadata/julia/makie.yaml new file mode 100644 index 0000000000..af8e70adf4 --- /dev/null +++ b/plots/count-basic/metadata/julia/makie.yaml @@ -0,0 +1,240 @@ +library: makie +language: julia +specification_id: count-basic +created: '2026-08-11T07:21:05Z' +updated: '2026-08-11T07:52:50Z' +generated_by: claude-sonnet +workflow_run: 31468309306 +issue: 2033 +language_version: 1.11.9 +library_version: 0.21.9 +preview_url_light: https://storage.googleapis.com/anyplot-images/plots/count-basic/julia/makie/plot-light.png +preview_url_dark: https://storage.googleapis.com/anyplot-images/plots/count-basic/julia/makie/plot-dark.png +preview_html_light: null +preview_html_dark: null +quality_score: 87 +review: + strengths: + - 'Both fixes requested in attempt 1 are now correctly rendered in this fresh render + (unlike the stale artifact reviewed in attempt 2): larger title (titlesize 20->27) + and a leading-category emphasis (ink stroke outline + "342 (36% of responses)" + callout)' + - Genuine count-plot semantics -- raw per-respondent device_pool tallied via a Dict, + not pre-aggregated bar values + - Descending sort + count labels + leading-bar emphasis create clear visual hierarchy + and an at-a-glance takeaway + - Theme-adaptive chrome correctly threaded through both renders; data color identical + (#009E73) across light/dark + - 'Clean, idiomatic Makie script: Figure/Axis/barplot!/text!, Random.seed!(42), + no unused imports, saves as plot-$(THEME).png' + weaknesses: + - Title still sits below the general 50-70% width guideline (~30%) though it now + matches the specific titlesize value requested previously -- acceptable, no further + action required + - Visual refinement (DE-02) stays close to the mandated house-style baseline; extra + polish (e.g. subtle bar-opacity gradient by rank, refined typography for the callout) + would raise marks further + - Library Mastery (LM-02) remains modest -- the stroke-highlight technique is easily + replicated in other libraries; a more Makie-distinctive touch (e.g. Legend, custom + Theme block) would differentiate it further + image_description: |- + Light render (plot-light.png): + Background: Warm off-white, consistent with #FAF8F1 (not pure white, not dark) + Chrome: Bold dark-ink title "count-basic · julia · makie · anyplot.ai" centered top; x-axis label "Primary Device Used for Survey" and y-axis label "Number of Respondents" in dark ink; tick labels in softer grey-ink; only left/bottom spines visible; subtle horizontal-only gridlines. All confirmed readable. + Data: Six brand-green (#009E73) bars sorted descending -- Smartphone (342), Laptop (268), Tablet (145), Desktop (98), Smartwatch (61), E-reader (24). Leading "Smartphone" bar has a dark ink stroke outline and bold callout "342 (36% of responses)"; other bars have plain soft-grey count labels. First series confirmed #009E73. + Legibility verdict: PASS + + Dark render (plot-dark.png): + Background: Warm near-black, consistent with #1A1A17 (not pure black, not light) + Chrome: Same title/axis labels/ticks now in light ink (white title/axis labels, soft light-grey ticks and secondary count labels) against the dark surface. No dark-on-dark failures -- all text clearly visible. + Data: Bars remain identical brand green (#009E73) to the light render, same values/ordering. Leading bar's stroke outline renders in light ink (theme-adaptive) with the "342 (36% of responses)" callout in bright white. + Legibility verdict: PASS + criteria_checklist: + visual_quality: + score: 29 + max: 30 + items: + - id: VQ-01 + name: Text Legibility + score: 7 + max: 8 + passed: true + comment: Explicit sizes throughout, readable in both themes; title now fills + ~30% of canvas width (up from ~20% pre-fix) + - id: VQ-02 + name: No Overlap + score: 6 + max: 6 + passed: true + comment: No collisions between text, data, or annotations + - id: VQ-03 + name: Element Visibility + score: 6 + max: 6 + passed: true + comment: Bar width appropriate for 6 sparse categories + - id: VQ-04 + name: Color Accessibility + score: 2 + max: 2 + passed: true + comment: Single accent color, CVD-safe, highlight via stroke not hue + - id: VQ-05 + name: Layout & Canvas + score: 4 + max: 4 + passed: true + comment: 3200x1800 canvas confirmed, balanced axis labels, no overflow/cutoff + - id: VQ-06 + name: Axis Labels & Title + score: 2 + max: 2 + passed: true + comment: Descriptive axis labels with units/context + - id: VQ-07 + name: Palette Compliance + score: 2 + max: 2 + passed: true + comment: 'First series #009E73, correct theme backgrounds, data colors identical + across themes' + design_excellence: + score: 12 + max: 20 + items: + - id: DE-01 + name: Aesthetic Sophistication + score: 5 + max: 8 + passed: false + comment: Leading-bar stroke outline is a deliberate accent beyond flat defaults, + rest of palette minimal + - id: DE-02 + name: Visual Refinement + score: 3 + max: 6 + passed: false + comment: Spine removal and subtle gridline match house-style baseline; limited + extra polish + - id: DE-03 + name: Data Storytelling + score: 4 + max: 6 + passed: false + comment: Percentage-of-total callout + stroke outline on leading category + gives an immediate takeaway + spec_compliance: + score: 15 + max: 15 + items: + - id: SC-01 + name: Plot Type + score: 5 + max: 5 + passed: true + comment: Correct count plot -- raw data tallied, not pre-aggregated + - id: SC-02 + name: Required Features + score: 4 + max: 4 + passed: true + comment: Sorted descending, count labels, optional percentage annotation on + leader + - id: SC-03 + name: Data Mapping + score: 3 + max: 3 + passed: true + comment: X=categories, Y=counts, all data shown + - id: SC-04 + name: Title & Legend + score: 3 + max: 3 + passed: true + comment: Title matches mandated format exactly, no legend needed for single + series + data_quality: + score: 15 + max: 15 + items: + - id: DQ-01 + name: Feature Coverage + score: 6 + max: 6 + passed: true + comment: All 6 categories shown, sorted, labeled, leader highlighted + - id: DQ-02 + name: Realistic Context + score: 5 + max: 5 + passed: true + comment: Plausible neutral device-usage survey data + - id: DQ-03 + name: Appropriate Scale + score: 4 + max: 4 + passed: true + comment: Values 24-342, sensible for a survey sample + code_quality: + score: 10 + max: 10 + items: + - id: CQ-01 + name: KISS Structure + score: 3 + max: 3 + passed: true + comment: No functions/classes, flat script + - id: CQ-02 + name: Reproducibility + score: 2 + max: 2 + passed: true + comment: Random.seed!(42) + - id: CQ-03 + name: Clean Imports + score: 2 + max: 2 + passed: true + comment: CairoMakie, Colors, Random -- all used + - id: CQ-04 + name: Code Elegance + score: 2 + max: 2 + passed: true + comment: Appropriate complexity, no fake UI + - id: CQ-05 + name: Output & API + score: 1 + max: 1 + passed: true + comment: Saves as plot-$(THEME).png with px_per_unit=2 + library_mastery: + score: 6 + max: 10 + items: + - id: LM-01 + name: Idiomatic Usage + score: 4 + max: 5 + passed: true + comment: Figure/Axis/barplot!/text! used idiomatically + - id: LM-02 + name: Distinctive Features + score: 2 + max: 5 + passed: false + comment: Per-element strokewidth vector and conditional text! are modest, + replicable-elsewhere touches + verdict: APPROVED +impl_tags: + dependencies: [] + techniques: + - annotations + - manual-ticks + patterns: + - data-generation + dataprep: [] + styling: + - edge-highlighting + - publication-ready