{"spec_id":"rug-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# rug-basic: Basic Rug Plot\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 92/100 | Created: 2026-07-25\n\nusing CairoMakie\nusing Colors\nusing Random\n\n# Theme tokens (see prompts/default-style-guide.md \"Background\" + \"Theme-adaptive Chrome\")\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 IMPRINT_PALETTE = [\n    colorant\"#009E73\", colorant\"#C475FD\", colorant\"#4467A3\", colorant\"#BD8233\",\n    colorant\"#AE3030\", colorant\"#2ABCCD\", colorant\"#954477\", colorant\"#99B314\",\n]\nconst BRAND = IMPRINT_PALETTE[1]  # Imprint palette position 1 — ALWAYS first series\n\n# Data — bimodal commute durations (light-traffic vs. heavy-traffic days)\nRandom.seed!(42)\nlight_traffic_days = 18.0 .+ 3.0 .* randn(110)\nheavy_traffic_days = 32.0 .+ 4.0 .* randn(70)\ncommute_minutes = vcat(light_traffic_days, heavy_traffic_days)\n\ntitle_str = \"Daily Commute Duration · rug-basic · julia · makie · anyplot.ai\"\n\n# Plot — stacked panels sharing an x-axis: histogram on top, rug strip below\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax_hist = Axis(\n    fig[1, 1];\n    title             = title_str,\n    titlesize         = 20,\n    titlecolor        = INK,\n    ylabel            = \"Number of Days\",\n    ylabelsize        = 14,\n    ylabelcolor       = INK,\n    yticklabelsize    = 12,\n    yticklabelcolor   = INK_SOFT,\n    ytickcolor        = INK_SOFT,\n    backgroundcolor   = PAGE_BG,\n    topspinevisible   = false,\n    rightspinevisible = false,\n    bottomspinevisible = false,\n    leftspinecolor    = INK_SOFT,\n    ygridvisible      = true,\n    ygridcolor        = RGBAf(INK.r, INK.g, INK.b, 0.15),\n    xgridvisible      = false,\n)\n\nax_rug = Axis(\n    fig[2, 1];\n    xlabel            = \"Commute Duration (minutes)\",\n    xlabelsize        = 14,\n    xlabelcolor       = INK,\n    xticklabelsize    = 12,\n    xticklabelcolor   = INK_SOFT,\n    xtickcolor        = INK_SOFT,\n    backgroundcolor   = PAGE_BG,\n    topspinevisible   = false,\n    rightspinevisible = false,\n    leftspinevisible  = false,\n    bottomspinecolor  = INK_SOFT,\n)\nhideydecorations!(ax_rug)\n\nbin_edges = range(minimum(commute_minutes), maximum(commute_minutes); length = 17)\nhist!(ax_hist, commute_minutes;\n      bins = bin_edges, color = (BRAND, 0.6), strokecolor = PAGE_BG, strokewidth = 1.2)\n\n# Callout distinguishing the two commute modes revealed by the bimodal shape,\n# positioned relative to each cluster's mean within the shared data range\nxmin, xmax = extrema(commute_minutes)\nlight_rel = (sum(light_traffic_days) / length(light_traffic_days) - xmin) / (xmax - xmin)\nheavy_rel = (sum(heavy_traffic_days) / length(heavy_traffic_days) - xmin) / (xmax - xmin)\ntext!(ax_hist, light_rel, 0.98; text = \"light traffic\", align = (:center, :top),\n      space = :relative, fontsize = 12, color = INK_SOFT)\ntext!(ax_hist, heavy_rel, 0.98; text = \"heavy traffic\", align = (:center, :top),\n      space = :relative, fontsize = 12, color = INK_SOFT)\n\n# Rug ticks — one short vertical segment per observation, thin and light so\n# density variation stays legible even where observations overlap heavily\nrug_segments = Vector{Point2f}(undef, 2 * length(commute_minutes))\nfor (i, v) in enumerate(commute_minutes)\n    rug_segments[2i - 1] = Point2f(v, 0.15)\n    rug_segments[2i]     = Point2f(v, 0.85)\nend\nlinesegments!(ax_rug, rug_segments; color = (BRAND, 0.25), linewidth = 1.5)\n\nlinkxaxes!(ax_hist, ax_rug)\nylims!(ax_rug, 0, 1)\nrowsize!(fig.layout, 2, Relative(0.14))\nrowgap!(fig.layout, 1, 6)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}