{"spec_id":"line-multi","library":"makie","language":"julia","code":"# anyplot.ai\n# line-multi: Multi-Line Comparison Plot\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 93/100 | Created: 2026-08-05\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 ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\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]\n\n# --- Data ---------------------------------------------------------------\n# Indexed revenue (base = 100) for 4 product lines over 36 months, each\n# following a random walk with its own drift so the lines diverge visibly.\nn_months = 36\nmonths = 1:n_months\nproduct_lines = [\"Core Platform\", \"Mobile App\", \"Analytics Suite\", \"API Services\"]\ndrifts = [0.35, 1.15, -0.25, 0.75]\nvols = [1.6, 2.4, 2.0, 2.8]\n\nrevenue_index = Array{Float64}(undef, n_months, length(product_lines))\nfor (i, (drift, vol)) in enumerate(zip(drifts, vols))\n    steps = drift .+ vol .* randn(n_months)\n    revenue_index[:, i] = 100.0 .+ cumsum(steps) .- steps[1]\nend\n\n# Headline series: the largest cumulative % change gets a bolder line and a\n# callout so the chart guides the eye instead of reading as four\n# equally-weighted lines.\npct_change = (revenue_index[end, :] .- 100.0) ./ 100.0 .* 100.0\nheadline = argmax(pct_change)\n\n# --- Plot -----------------------------------------------------------------\ntitle_str = \"line-multi · julia · makie · anyplot.ai\"\n\nfig = Figure(\n    resolution      = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = title_str,\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Month\",\n    ylabel             = \"Revenue Index (base = 100)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridvisible       = false,\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.15),\n    yticks             = LinearTicks(9),\n)\n\nseries!(ax, months, revenue_index'; color = IMPRINT_PALETTE, labels = product_lines, linewidth = 2.5)\n\n# Overlay the headline series with a bolder line + endpoint callout.\nlines!(ax, months, revenue_index[:, headline]; color = IMPRINT_PALETTE[headline], linewidth = 4.5)\ntext!(ax, months[end], revenue_index[end, headline];\n    text     = \"$(product_lines[headline]) $(pct_change[headline] >= 0 ? \"+\" : \"\")$(round(Int, pct_change[headline]))%\",\n    color    = IMPRINT_PALETTE[headline],\n    fontsize = 13,\n    align    = (:right, :bottom),\n    offset   = (-6, 8),\n)\n\naxislegend(ax; position = :lt, framevisible = true, backgroundcolor = ELEVATED_BG,\n    framecolor = INK_SOFT, labelcolor = INK_SOFT, labelsize = 12, patchsize = (20, 12))\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}