{"spec_id":"area-stacked","library":"makie","language":"julia","code":"# anyplot.ai\n# area-stacked: Stacked Area Chart\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 87/100 | Created: 2026-08-17\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# --- Theme tokens -------------------------------------------------------------\nTHEME    = get(ENV, \"ANYPLOT_THEME\", \"light\")\nPAGE_BG  = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nINK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nINK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nIMPRINT_PALETTE = [\n    colorant\"#009E73\", colorant\"#C475FD\", colorant\"#4467A3\", colorant\"#BD8233\",\n]\n\n# --- Data -----------------------------------------------------------------------\n# Monthly revenue ($ thousands) by product category, two years — largest series first\nmonths = 1:24\nmonth_labels = [\"Jan 2024\", \"Apr 2024\", \"Jul 2024\", \"Oct 2024\",\n                \"Jan 2025\", \"Apr 2025\", \"Jul 2025\", \"Oct 2025\"]\n\nelectronics = 42 .+ 0.9 .* months .+ 4 .* sin.(months ./ 3) .+ randn(24) .* 3\nhome_goods  = 26 .+ 0.4 .* months .+ 3 .* sin.(months ./ 4 .+ 1) .+ randn(24) .* 2.5\napparel     = 18 .+ 0.15 .* months .+ 5 .* sin.(months ./ 6 .+ 2) .+ randn(24) .* 2\nsporting    = 10 .+ 0.25 .* months .+ 2 .* sin.(months ./ 5) .+ randn(24) .* 1.5\n\nelectronics = max.(electronics, 5)\nhome_goods  = max.(home_goods, 4)\napparel     = max.(apparel, 3)\nsporting    = max.(sporting, 2)\n\nbaseline = zeros(24)\ncum1 = electronics\ncum2 = cum1 .+ home_goods\ncum3 = cum2 .+ apparel\ncum4 = cum3 .+ sporting\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               = \"area-stacked · julia · makie · anyplot.ai\",\n    titlesize           = 25,\n    titlecolor          = INK,\n    xlabel              = \"Month\",\n    ylabel              = \"Revenue (\\$ thousands)\",\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    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    xticks              = (1:3:22, month_labels),\n    xticklabelrotation  = pi / 6,\n)\n\nband!(ax, months, baseline, cum1; color = (IMPRINT_PALETTE[1], 0.85))\nband!(ax, months, cum1, cum2; color = (IMPRINT_PALETTE[2], 0.85))\nband!(ax, months, cum2, cum3; color = (IMPRINT_PALETTE[3], 0.85))\nband!(ax, months, cum3, cum4; color = (IMPRINT_PALETTE[4], 0.85))\n\nlines!(ax, months, cum1; color = IMPRINT_PALETTE[1], linewidth = 2.5)\nlines!(ax, months, cum2; color = IMPRINT_PALETTE[2], linewidth = 2)\nlines!(ax, months, cum3; color = IMPRINT_PALETTE[3], linewidth = 2)\nlines!(ax, months, cum4; color = IMPRINT_PALETTE[4], linewidth = 2)\n\nylims!(ax, 0, nothing)\nxlims!(ax, 0.5, 29)\n\n# Data-storytelling focal point: an end-of-line value label for Electronics\n# (the dominant series), placed in the margin whitespace beyond the last data\n# point so it reads against the page background — not against the colored\n# fill — and stays legible in both themes without fighting CairoMakie's\n# per-vertex triangulated color interpolation on `band!`.\nlines!(ax, [months[end], months[end] + 1], [cum1[end], cum1[end]];\n       color = INK_SOFT, linewidth = 1)\ntext!(ax, months[end] + 1.2, cum1[end];\n      text = \"Electronics\\n\\$$(round(Int, electronics[end]))k\",\n      color = INK, fontsize = 13, align = (:left, :center))\n\nlegend_labels = [\"Electronics\", \"Home Goods\", \"Apparel\", \"Sporting Goods\"]\nlegend_elements = [PolyElement(color = (c, 0.85)) for c in IMPRINT_PALETTE]\naxislegend(ax, legend_elements, legend_labels; position = :lt, labelcolor = INK_SOFT, framevisible = false)\n\n# --- Save -----------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}