{"spec_id":"bar-stacked","library":"makie","language":"julia","code":"# anyplot.ai\n# bar-stacked: Stacked Bar Chart\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 89/100 | Created: 2026-09-02\n\nusing CairoMakie\nusing Colors\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\"\n\n# Imprint categorical palette — 8 hues, theme-independent, hybrid-v3 sort\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 — brand green (ALWAYS first series)\n    colorant\"#C475FD\",  # 2 — lavender\n    colorant\"#4467A3\",  # 3 — blue\n    colorant\"#BD8233\",  # 4 — ochre\n]\n\n# --- Data ---------------------------------------------------------------------\n# Monthly grid-generation mix (GWh): fossil sources receding, renewables rising.\nmonths = [\"Jan\", \"Feb\", \"Mar\", \"Apr\", \"May\", \"Jun\", \"Jul\", \"Aug\"]\nn_months = length(months)\n\nsolar       = [6.0, 8.0, 10.0, 12.0, 15.0, 17.0, 19.0, 20.0]\nwind        = [10.0, 11.0, 13.0, 15.0, 17.0, 19.0, 21.0, 22.0]\nnatural_gas = [30.0, 29.0, 28.0, 28.0, 27.0, 27.0, 26.0, 26.0]\ncoal        = [42.0, 38.0, 34.0, 30.0, 28.0, 26.0, 25.0, 24.0]\ntotals = coal .+ natural_gas .+ wind .+ solar\n\n# Legend/color order (canonical Imprint 1→4): solar, wind, natural gas, coal.\nsolar_color, wind_color, gas_color, coal_color = IMPRINT_PALETTE\n\n# Visual stack order (bottom → top): coal, natural gas, wind, solar — legacy\n# baseload at the bottom, emerging renewables on top.\nx_idx  = repeat(1:n_months, outer = 4)\nstack  = vcat(fill(1, n_months), fill(2, n_months), fill(3, n_months), fill(4, n_months))\nvalues = vcat(coal, natural_gas, wind, solar)\ncolors = vcat(\n    fill(coal_color, n_months),\n    fill(gas_color, n_months),\n    fill(wind_color, n_months),\n    fill(solar_color, n_months),\n)\n\n# --- Plot ----------------------------------------------------------------------\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"bar-stacked · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Month\",\n    ylabel             = \"Electricity Generation (GWh)\",\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)\nax.xticks = (1:n_months, months)\n\nbarplot!(\n    ax, x_idx, values;\n    stack = stack, color = colors, width = 0.72,\n    strokewidth = 1.25, strokecolor = PAGE_BG,\n)\n\ntext!(\n    ax, 1:n_months, totals;\n    text  = [string(round(Int, t)) for t in totals],\n    align = (:center, :bottom),\n    offset = (0, 6),\n    color = INK,\n    fontsize = 14,\n    font = :bold,\n    strokewidth = 0.75,\n    strokecolor = PAGE_BG,\n)\n\nylims!(ax, 0, maximum(totals) * 1.18)\n\nelements = [PolyElement(color = c) for c in IMPRINT_PALETTE]\nLegend(\n    fig[1, 2], elements, [\"Solar\", \"Wind\", \"Natural Gas\", \"Coal\"], \"Energy Source\";\n    framevisible = false,\n    labelcolor   = INK,\n    labelsize    = 13,\n    titlecolor   = INK,\n    titlesize    = 14,\n    titlefont    = :bold,\n    titlehalign  = :left,\n)\n\n# --- Save -----------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}