Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
103 changes: 103 additions & 0 deletions plots/count-basic/implementations/julia/makie.jl
Original file line number Diff line number Diff line change
@@ -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)
240 changes: 240 additions & 0 deletions plots/count-basic/metadata/julia/makie.yaml
Original file line number Diff line number Diff line change
@@ -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