{"spec_id":"heatmap-adjacency","library":"makie","language":"julia","code":"# anyplot.ai\n# heatmap-adjacency: Network Adjacency Matrix Heatmap\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 88/100 | Created: 2026-09-05\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\"\n\n# Continuous colormap — sequential, single-polarity (collaboration strength)\nconst ANYPLOT_SEQ = cgrad([colorant\"#009E73\", colorant\"#4467A3\"])\n\n# --- Data ---------------------------------------------------------------\n# Cross-team collaboration network: employees grouped by team, weight =\n# frequency of joint project work. Nodes are pre-ordered by team so the\n# within-team block-diagonal structure is immediately visible.\nteam_names = [\"Engineering\", \"Design\", \"Sales\", \"Marketing\"]\nteam_sizes = [9, 6, 7, 8]\nn_nodes = sum(team_sizes)\nnode_team = vcat([fill(i, team_sizes[i]) for i in eachindex(team_sizes)]...)\n\n# Undirected weighted adjacency matrix — both triangles filled symmetrically.\n# Absent edges (including the diagonal) stay NaN so they render as a\n# distinct background color rather than a low-intensity data color.\ncollaboration = fill(NaN, n_nodes, n_nodes)\nfor i in 1:n_nodes, j in (i + 1):n_nodes\n    same_team = node_team[i] == node_team[j]\n    connected = same_team ? rand() < 0.75 : rand() < 0.12\n    if connected\n        weight = same_team ? 0.55 + rand() * 0.45 : 0.05 + rand() * 0.30\n        collaboration[i, j] = weight\n        collaboration[j, i] = weight\n    end\nend\n\n# Group boundaries (between blocks) and centers (for tick labels)\ncum_sizes = cumsum(team_sizes)\nboundaries = cum_sizes[1:(end - 1)] .+ 0.5\ncenters = cum_sizes .- team_sizes ./ 2 .+ 0.5\n\n# --- Plot -----------------------------------------------------------------\nfig = Figure(\n    size            = (1200, 1200),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"heatmap-adjacency · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    subtitle           = \"$(n_nodes) nodes, ordered by team\",\n    subtitlesize       = 13,\n    subtitlecolor      = INK_SOFT,\n    xlabel             = \"Target\",\n    ylabel             = \"Source\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticks             = (centers, team_names),\n    yticks             = (centers, team_names),\n    xticklabelsize     = 13,\n    yticklabelsize     = 13,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    # Unlabeled per-node minor ticks confirm the true 30x30 node density\n    # underneath the 4 labeled team blocks.\n    xminorticksvisible = true,\n    yminorticksvisible = true,\n    xminorticks        = 0.5:1:(n_nodes + 0.5),\n    yminorticks        = 0.5:1:(n_nodes + 0.5),\n    xminortickalign    = 1,\n    yminortickalign    = 1,\n    xminortickcolor    = INK_SOFT,\n    yminortickcolor    = INK_SOFT,\n    xminorticksize     = 3,\n    yminorticksize     = 3,\n    backgroundcolor    = PAGE_BG,\n    aspect             = DataAspect(),\n    # Enclosed heatmap grid — style-guide spine exception keeps all 4 sides.\n    topspinevisible    = true,\n    rightspinevisible  = true,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    topspinecolor      = INK_SOFT,\n    rightspinecolor    = INK_SOFT,\n    xgridvisible       = false,\n    ygridvisible       = false,\n)\nax.yreversed = true\n\nhm = heatmap!(\n    ax, collaboration;\n    colormap   = ANYPLOT_SEQ,\n    colorrange = (0.0, 1.0),\n    nan_color  = PAGE_BG,\n)\n\nvlines!(ax, boundaries; color = INK_SOFT, linewidth = 1.5)\nhlines!(ax, boundaries; color = INK_SOFT, linewidth = 1.5)\n\nColorbar(\n    fig[1, 2], hm;\n    label           = \"Collaboration Strength\",\n    labelcolor      = INK,\n    labelsize       = 14,\n    ticklabelcolor  = INK_SOFT,\n    ticklabelsize   = 13,\n    tickcolor       = INK_SOFT,\n    width           = 25,\n)\ncolgap!(fig.layout, 20)\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}