{"spec_id":"count-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# count-basic: Basic Count Plot\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 82/100 | Updated: 2026-09-27\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# --- Theme tokens -----------------------------------------------------------\nconst THEME    = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG  = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst INK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst BRAND    = colorant\"#009E73\"  # Imprint palette position 1 — ALWAYS first series\n\n# --- Data ---------------------------------------------------------------\n# Raw per-session device type from a web analytics log — count-basic tallies\n# occurrences from unaggregated observations rather than pre-computed values.\ndevice_types  = [\"Desktop\", \"Mobile\", \"Tablet\", \"Smart TV\", \"Wearable\"]\nsession_share = [820, 1150, 340, 95, 45]  # underlying popularity per device\nraw_sessions = reduce(vcat, [fill(device, n) for (device, n) in zip(device_types, session_share)])\nshuffle!(raw_sessions)\n\nsession_counts = Dict{String,Int}()\nfor device in raw_sessions\n    session_counts[device] = get(session_counts, device, 0) + 1\nend\n\n# Sorted by frequency, descending\nsorted_devices = sort(collect(keys(session_counts)); by = d -> session_counts[d], rev = true)\nsorted_counts  = [session_counts[d] for d in sorted_devices]\n\n# --- Plot -----------------------------------------------------------------\nfig = Figure(\n    resolution      = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title             = \"Device Type Sessions · count-basic · julia · makie · anyplot.ai\",\n    titlesize         = 20,\n    titlecolor        = INK,\n    xlabel            = \"Device Type\",\n    ylabel            = \"Sessions\",\n    xlabelsize        = 16,\n    ylabelsize        = 16,\n    xlabelcolor       = INK,\n    ylabelcolor       = INK,\n    xticklabelsize    = 13,\n    yticklabelsize    = 13,\n    xticklabelcolor   = INK_SOFT,\n    yticklabelcolor   = INK_SOFT,\n    xtickcolor        = INK_SOFT,\n    ytickcolor        = INK_SOFT,\n    backgroundcolor   = PAGE_BG,\n    leftspinecolor    = INK_SOFT,\n    bottomspinecolor  = INK_SOFT,\n    xgridvisible      = false,\n    ygridcolor        = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    xticks            = (1:length(sorted_devices), sorted_devices),\n)\nhidespines!(ax, :t, :r)\n\nbarplot!(\n    ax, 1:length(sorted_devices), sorted_counts;\n    color = BRAND, width = 0.62,\n    strokewidth = 1.5, strokecolor = PAGE_BG,\n)\n\ntotal_sessions = sum(sorted_counts)\nfor (i, count) in enumerate(sorted_counts)\n    text!(\n        ax, i, count;\n        text = string(count),\n        align = (:center, :bottom),\n        offset = (0, 6),\n        fontsize = 14,\n        color = INK,\n    )\n    pct = round(100 * count / total_sessions; digits = 1)\n    text!(\n        ax, i, count;\n        text = \"($(pct)%)\",\n        align = (:center, :bottom),\n        offset = (0, 24),\n        fontsize = 11,\n        color = INK_SOFT,\n    )\nend\n\nylims!(ax, 0, maximum(sorted_counts) * 1.2)\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}