{"spec_id":"subplot-grid","library":"makie","language":"julia","code":"# anyplot.ai\n# subplot-grid: Subplot Grid Layout\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 94/100 | Created: 2026-09-09\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 GRID_RGBA = RGBAf(INK.r, INK.g, INK.b, 0.15)\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# Financial dashboard: closing price, trading volume, return distribution,\n# and how daily volume relates to the size of the day's price move.\nn_days = 90\ntrading_day = 1:n_days\n\ndaily_pct_change = randn(n_days) .* 0.015\nprice = 150 .* cumprod(1 .+ daily_pct_change)\ndaily_return = diff(price) ./ price[1:(end - 1)] .* 100\n\nvolume = 1.2e6 .+ 4.5e6 .* abs.(daily_pct_change) .+ 3e5 .* randn(n_days)\nvolume = max.(volume, 2e5)\n\n# Focal points for the dashboard's two linked panels — highlighted via color/size\n# emphasis rather than text callouts (the spec doesn't request annotations).\npeak_day    = argmax(price)\nspike_day   = argmax(volume)\nprice_floor = minimum(price) * 0.985\n\n# --- Plot -----------------------------------------------------------------\nfig = Figure(\n    resolution      = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nLabel(\n    fig[0, 1:2],\n    \"subplot-grid · julia · makie · anyplot.ai\";\n    fontsize = 22,\n    color    = INK,\n    font     = :bold,\n    padding  = (0, 0, 8, 0),\n)\n\nchrome = (;\n    backgroundcolor   = PAGE_BG,\n    titlecolor        = INK,\n    xlabelcolor       = INK,\n    ylabelcolor       = INK,\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    xminorgridvisible = false,\n    yminorgridvisible = false,\n)\n\nax_price = Axis(\n    fig[1, 1];\n    title               = \"Price Trend\",\n    titlesize           = 15,\n    ylabel              = \"Price (USD)\",\n    ylabelsize          = 14,\n    xticklabelsvisible  = false,\n    xgridvisible        = false,\n    ygridcolor          = GRID_RGBA,\n    chrome...,\n)\n\nax_hist = Axis(\n    fig[1, 2];\n    title        = \"Return Distribution\",\n    titlesize    = 15,\n    xlabel       = \"Daily Return (%)\",\n    ylabel       = \"Trading Days\",\n    xlabelsize   = 14,\n    ylabelsize   = 14,\n    xgridvisible = false,\n    ygridcolor   = GRID_RGBA,\n    chrome...,\n)\n\nax_volume = Axis(\n    fig[2, 1];\n    title        = \"Trading Volume\",\n    titlesize    = 15,\n    xlabel       = \"Trading Day\",\n    ylabel       = \"Volume (shares)\",\n    xlabelsize   = 14,\n    ylabelsize   = 14,\n    xgridvisible = false,\n    ygridcolor   = GRID_RGBA,\n    chrome...,\n)\n\nax_scatter = Axis(\n    fig[2, 2];\n    title         = \"Volume vs. Return\",\n    titlesize     = 15,\n    xlabel        = \"Daily Return (%)\",\n    ylabel        = \"Volume (shares)\",\n    xlabelsize    = 14,\n    ylabelsize    = 14,\n    xgridcolor    = GRID_RGBA,\n    ygridcolor    = GRID_RGBA,\n    chrome...,\n)\n\n# Price and volume share the trading-day axis — a real dashboard comparison.\nlinkxaxes!(ax_price, ax_volume)\n\nband!(\n    ax_price, trading_day, fill(price_floor, n_days), price;\n    color = (IMPRINT_PALETTE[1], 0.12),\n)\nlines!(ax_price, trading_day, price; color = IMPRINT_PALETTE[1], linewidth = 2.5)\nscatter!(\n    ax_price, [peak_day], [price[peak_day]];\n    color = IMPRINT_PALETTE[1], markersize = 15,\n    strokewidth = 2, strokecolor = PAGE_BG,\n)\n\nhist!(\n    ax_hist, daily_return;\n    bins = 16, color = IMPRINT_PALETTE[2],\n    strokewidth = 1, strokecolor = PAGE_BG,\n)\n\nvolume_colors = [\n    d == spike_day ? IMPRINT_PALETTE[3] : RGBAf(IMPRINT_PALETTE[3].r, IMPRINT_PALETTE[3].g, IMPRINT_PALETTE[3].b, 0.6)\n    for d in trading_day\n]\nbarplot!(\n    ax_volume, trading_day, volume;\n    color = volume_colors, width = 0.8,\n    strokewidth = 0.5, strokecolor = PAGE_BG,\n)\n\nscatter!(\n    ax_scatter, daily_return, volume[2:end];\n    color = IMPRINT_PALETTE[4], markersize = 10, strokewidth = 0,\n)\n\ncolgap!(fig.layout, 40)\nrowgap!(fig.layout, 28)\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}