{"spec_id":"heatmap-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# heatmap-basic: Basic Heatmap\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 88/100 | Created: 2026-05-28\n\nusing CairoMakie\nusing Colors\nusing Random\nusing Statistics\nusing Printf\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\"\n\n# Imprint diverging colormap (correlation data: meaningful midpoint at zero)\nconst _midpoint   = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ANYPLOT_DIV = cgrad([colorant\"#AE3030\", _midpoint, colorant\"#4467A3\"])\n\n# Data — climate variables, 200 daily observations\n# Grouped by natural cluster for visual story:\n#   warm-moisture: Temp, Dewpoint, Humidity, Precip\n#   atmospheric:   Wind, Pressure, Clouds, UV Index\nvar_labels = [\"Temp\", \"Dewpoint\", \"Humidity\", \"Precip\", \"Wind\", \"Pressure\", \"Clouds\", \"UV Index\"]\nn          = length(var_labels)\n\nobs_raw = zeros(200, 8)\nobs_raw[:, 1] = randn(200)                                                             # Temperature\nobs_raw[:, 6] = 0.85 .* obs_raw[:, 1] .+ 0.53 .* randn(200)                          # Dewpoint ~ Temp\nobs_raw[:, 2] = 0.45 .* obs_raw[:, 1] .+ 0.45 .* obs_raw[:, 6] .+ 0.45 .* randn(200) # Humidity\nobs_raw[:, 5] = 0.55 .* obs_raw[:, 2] .+ 0.84 .* randn(200)                          # Precip ~ Humidity\nobs_raw[:, 8] = 0.40 .* obs_raw[:, 5] .+ 0.92 .* randn(200)                          # Clouds ~ Precip\nobs_raw[:, 7] = -0.55 .* obs_raw[:, 8] .+ 0.84 .* randn(200)                         # UV Index ~ -Clouds\nobs_raw[:, 3] = 0.15 .* obs_raw[:, 1] .+ 0.99 .* randn(200)                          # Wind (mostly noise)\nobs_raw[:, 4] = -0.25 .* obs_raw[:, 1] .+ 0.97 .* randn(200)                         # Pressure ~ -Temp\n\n# Reorder: [Temp=1, Dewpoint=6, Humidity=2, Precip=5 | Wind=3, Pressure=4, Clouds=8, UV=7]\nobs      = obs_raw[:, [1, 6, 2, 5, 3, 4, 8, 7]]\ncorr_mat = cor(obs)\n\n# Square canvas for symmetric heatmap\nfig = Figure(\n    size            = (1200, 1200),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"heatmap-basic · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    subtitle           = \"Climate Variables · 200 Daily Observations\",\n    subtitlesize       = 13,\n    subtitlecolor      = INK_SOFT,\n    xlabel             = \"\",\n    ylabel             = \"\",\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xticksize          = 0,\n    yticksize          = 0,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinevisible   = false,\n    bottomspinevisible = false,\n    xgridvisible       = false,\n    ygridvisible       = false,\n    xticks             = (1:n, var_labels),\n    yticks             = (1:n, var_labels),\n    xticklabelrotation = π / 4,\n    xticklabelsize     = 13,\n    yticklabelsize     = 13,\n    yreversed          = true,\n)\n\nhm = heatmap!(ax, 1:n, 1:n, corr_mat;\n    colormap   = ANYPLOT_DIV,\n    colorrange = (-1.0, 1.0),\n)\n\n# Thin cell grid lines — delineate cells, especially near-zero in dark theme\ncell_edges = [i + 0.5 for i in 0:n]\nvlines!(ax, cell_edges; color = RGBAf(INK.r, INK.g, INK.b, 0.20), linewidth = 0.6)\nhlines!(ax, cell_edges; color = RGBAf(INK.r, INK.g, INK.b, 0.20), linewidth = 0.6)\n\n# Highlight warm-moisture cluster (top-left 4×4 block: Temp/Dewpoint/Humidity/Precip)\nlines!(ax,\n    [0.5, 4.5, 4.5, 0.5, 0.5],\n    [0.5, 0.5, 4.5, 4.5, 0.5];\n    color     = colorant\"#009E73\",\n    linewidth = 3.0,\n)\n\n# Cell value annotations — fontsize=13 for mobile readability on dense 64-cell grid\npositions   = Point2f[]\ncell_labels = String[]\nfor i in 1:n, j in 1:n\n    push!(positions, Point2f(i, j))\n    push!(cell_labels, @sprintf(\"%.2f\", corr_mat[i, j]))\nend\ntext!(ax, positions; text = cell_labels, align = (:center, :center), color = INK, fontsize = 13)\n\n# Colorbar\nColorbar(fig[1, 2], hm;\n    label          = \"Pearson r\",\n    labelcolor     = INK,\n    tickcolor      = INK_SOFT,\n    ticklabelcolor = INK_SOFT,\n    ticklabelsize  = 12,\n    labelsize      = 13,\n    width          = 22,\n)\n\n# Fine-tune gap between heatmap and colorbar\ncolgap!(fig.layout, 1, 12)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}