{"spec_id":"heatmap-adjacency","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nheatmap-adjacency: Network Adjacency Matrix Heatmap\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 88/100 | Created: 2026-05-08\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_blank,\n    element_rect,\n    element_text,\n    geom_hline,\n    geom_tile,\n    geom_vline,\n    ggplot,\n    labs,\n    scale_fill_cmap,\n    scale_x_discrete,\n    scale_y_discrete,\n    theme,\n)\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\nABSENT_CELL = \"#E0DED7\" if THEME == \"light\" else \"#2A2A25\"\n\n# Data: researcher collaboration network — 3 scientific fields (Physics, Biology, CompSci)\nnp.random.seed(42)\n\nn_per_group = 10\nprefixes = [\"P\", \"B\", \"C\"]\nnode_names = [f\"{p}{i + 1:02d}\" for p in prefixes for i in range(n_per_group)]\nn_nodes = len(node_names)\n\nW = np.zeros((n_nodes, n_nodes))\n\n# Within-field: dense, strong collaborations (block-diagonal structure)\nfor gi in range(3):\n    members = list(range(gi * n_per_group, (gi + 1) * n_per_group))\n    for idx_i, i in enumerate(members):\n        for j in members[idx_i + 1 :]:\n            if np.random.rand() < 0.72:\n                w = np.random.uniform(0.45, 1.0)\n                W[i, j] = w\n                W[j, i] = w\n\n# Cross-field: sparse, weaker connections\nfor i in range(n_nodes):\n    for j in range(i + 1, n_nodes):\n        if i // n_per_group != j // n_per_group and W[i, j] == 0:\n            if np.random.rand() < 0.09:\n                w = np.random.uniform(0.05, 0.38)\n                W[i, j] = w\n                W[j, i] = w\n\n# Long-format DataFrame; absent edges (including diagonal) → NaN\nall_pairs = [(r, c) for r in range(n_nodes) for c in range(n_nodes)]\ndf = pd.DataFrame(\n    {\n        \"source\": pd.Categorical([node_names[r] for r, _ in all_pairs], categories=node_names, ordered=True),\n        \"target\": pd.Categorical([node_names[c] for _, c in all_pairs], categories=node_names, ordered=True),\n        \"weight\": [W[r, c] if W[r, c] > 0 else np.nan for r, c in all_pairs],\n    }\n)\n\n# Community separator positions (between groups of 10)\nboundaries = [n_per_group + 0.5, 2 * n_per_group + 0.5]\n\n# Plot\nanyplot_theme = theme(\n    figure_size=(12, 12),\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=ABSENT_CELL),\n    panel_grid_major=element_blank(),\n    panel_grid_minor=element_blank(),\n    panel_border=element_blank(),\n    axis_title=element_text(color=INK, size=20),\n    axis_text=element_text(color=INK_SOFT, size=16),\n    axis_text_x=element_text(angle=45, ha=\"right\", color=INK_SOFT, size=16),\n    plot_title=element_text(color=INK, size=24, ha=\"center\"),\n    legend_background=element_rect(fill=ELEVATED_BG, color=None),\n    legend_text=element_text(color=INK_SOFT, size=16),\n    legend_title=element_text(color=INK, size=18),\n)\n\nplot = (\n    ggplot(df, aes(x=\"target\", y=\"source\", fill=\"weight\"))\n    + geom_tile()\n    + geom_vline(xintercept=boundaries, color=INK, size=0.9, alpha=0.5, linetype=\"dashed\")\n    + geom_hline(yintercept=boundaries, color=INK, size=0.9, alpha=0.5, linetype=\"dashed\")\n    + scale_fill_cmap(\"viridis\", na_value=ABSENT_CELL, name=\"Collaboration\\nStrength\")\n    + scale_x_discrete(limits=node_names)\n    + scale_y_discrete(limits=node_names[::-1])\n    + labs(x=\"Target Researcher\", y=\"Source Researcher\", title=\"heatmap-adjacency · plotnine · anyplot.ai\")\n    + anyplot_theme\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=300, width=12, height=12, units=\"in\")\n"}