{"spec_id":"area-stacked-percent","library":"makie","language":"julia","code":"# anyplot.ai\n# area-stacked-percent: 100% Stacked Area Chart\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 93/100 | Created: 2026-09-02\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 IMPRINT_PALETTE = [\n    colorant\"#009E73\", colorant\"#C475FD\", colorant\"#4467A3\", colorant\"#BD8233\",\n    colorant\"#AE3030\", colorant\"#2ABCCD\", colorant\"#954477\", colorant\"#99B314\",\n]\n\n# --- Data -----------------------------------------------------------------\n# Quarterly revenue mix for a software vendor, shifting from perpetual\n# licenses/hardware toward subscription + support over three years.\nn_quarters   = 16\nquarter_of   = i -> ((i - 1) % 4) + 1\nyear_of      = i -> 2021 + div(i - 1, 4)\nquarter_lbls = [\"Q$(quarter_of(i)) $(year_of(i))\" for i in 1:n_quarters]\ncategories   = [\"Subscription\", \"Support\", \"Services\", \"Hardware\", \"License\"]\nn_categories = length(categories)\n\nprogress = range(0.0, 1.0, length = n_quarters)\n\nsubscription = 18.0 .+ 34.0 .* progress .^ 1.3 .+ randn(n_quarters) .* 1.5\nsupport      = 16.0 .+ 3.0  .* progress          .+ randn(n_quarters) .* 1.2\nservices     = 14.0 .+ 4.0  .* progress          .+ randn(n_quarters) .* 1.3\nhardware     = 20.0 .- 6.0  .* progress          .+ randn(n_quarters) .* 1.4\nlicense      = 34.0 .- 24.0 .* progress .^ 1.2   .+ randn(n_quarters) .* 1.5\n\nrevenue     = clamp.(hcat(subscription, support, services, hardware, license), 1.0, Inf)\npercentages = revenue ./ sum(revenue, dims = 2) .* 100.0\ncum_share   = cumsum(percentages, dims = 2)\n\nx = 1:n_quarters\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-percent · julia · makie · anyplot.ai\",\n    titlesize           = 22,\n    titlecolor          = INK,\n    xlabel              = \"Quarter\",\n    ylabel              = \"Share of Revenue\",\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    leftspinecolor      = INK_SOFT,\n    bottomspinecolor    = INK_SOFT,\n    topspinevisible     = false,\n    rightspinevisible   = false,\n    backgroundcolor     = PAGE_BG,\n    xticks              = (1:2:n_quarters, quarter_lbls[1:2:end]),\n    xticklabelrotation  = pi / 6,\n    yticks              = 0:20:100,\n    ytickformat         = ys -> [\"$(round(Int, y))%\" for y in ys],\n    xgridvisible        = false,\n    ygridcolor          = RGBAf(INK.r, INK.g, INK.b, 0.15),\n)\n\nxlims!(ax, 1, n_quarters)\nylims!(ax, 0, 100)\n\nfor k in 1:n_categories\n    lower_k = k == 1 ? zeros(n_quarters) : cum_share[:, k - 1]\n    upper_k = cum_share[:, k]\n    band!(ax, x, lower_k, upper_k; color = IMPRINT_PALETTE[k], label = categories[k])\n    lines!(ax, x, upper_k; color = PAGE_BG, linewidth = 1.5)\nend\n\nLegend(\n    fig[1, 2], ax, \"Product Line\";\n    labelsize       = 13,\n    labelcolor      = INK_SOFT,\n    titlesize       = 14,\n    titlecolor      = INK,\n    framevisible    = false,\n    backgroundcolor = PAGE_BG,\n)\n\ncolsize!(fig.layout, 1, Relative(0.85))\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}