{"spec_id":"heatmap-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nheatmap-basic: Basic Heatmap\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 92/100 | Updated: 2026-05-28\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove this script's directory from sys.path so \"matplotlib\" resolves to the\n# installed package rather than this file (which shares its name).\n_here = os.path.dirname(os.path.abspath(__file__))\nsys.path = [p for p in sys.path if os.path.abspath(p) != _here and p != \"\"]\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom matplotlib.colors import LinearSegmentedColormap, TwoSlopeNorm\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Imprint diverging colormap — theme-adaptive midpoint\nmidpoint = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nimprint_div = LinearSegmentedColormap.from_list(\"imprint_div\", [\"#AE3030\", midpoint, \"#4467A3\"])\n\n# Data — department cross-correlation matrix\n# Grouped: Revenue (Sales, Marketing, Finance), Technical (Dev, Ops, Support), Admin (HR, Legal)\ndepartments = [\"Sales\", \"Marketing\", \"Finance\", \"Dev\", \"Ops\", \"Support\", \"HR\", \"Legal\"]\nn = len(departments)\n\ndata = np.array(\n    [\n        [1.00, 0.82, 0.61, 0.12, 0.44, 0.35, -0.15, 0.08],  # Sales\n        [0.82, 1.00, 0.48, 0.18, 0.30, 0.28, 0.10, -0.20],  # Marketing\n        [0.61, 0.48, 1.00, -0.65, 0.05, -0.38, 0.30, 0.40],  # Finance\n        [0.12, 0.18, -0.65, 1.00, 0.42, 0.55, -0.10, -0.30],  # Dev\n        [0.44, 0.30, 0.05, 0.42, 1.00, 0.60, -0.08, 0.20],  # Ops\n        [0.35, 0.28, -0.38, 0.55, 0.60, 1.00, 0.22, 0.15],  # Support\n        [-0.15, 0.10, 0.30, -0.10, -0.08, 0.22, 1.00, 0.52],  # HR\n        [0.08, -0.20, 0.40, -0.30, 0.20, 0.15, 0.52, 1.00],  # Legal\n    ]\n)\n\n# Plot — square canvas for symmetric matrix (2400×2400 px)\nfig, ax = plt.subplots(figsize=(6, 6), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\nnorm = TwoSlopeNorm(vmin=-1, vcenter=0, vmax=1)\nim = ax.imshow(data, cmap=imprint_div, norm=norm, aspect=\"equal\")\n\n# Remove spines\nfor spine in ax.spines.values():\n    spine.set_visible(False)\n\n# Cell separators via minor-tick grid\nax.set_xticks(np.arange(n + 1) - 0.5, minor=True)\nax.set_yticks(np.arange(n + 1) - 0.5, minor=True)\nax.grid(which=\"minor\", color=PAGE_BG, linewidth=1.5)\nax.tick_params(which=\"minor\", bottom=False, left=False)\n\n# Tick labels\nax.set_xticks(np.arange(n))\nax.set_yticks(np.arange(n))\nax.set_xticklabels(departments, fontsize=8, rotation=45, ha=\"right\", color=INK_SOFT)\nax.set_yticklabels(departments, fontsize=8, color=INK_SOFT)\nax.tick_params(axis=\"both\", length=0, colors=INK_SOFT)\n\n# Group separator lines — Revenue / Technical / Admin clusters\nfor pos in [2.5, 5.5]:\n    ax.axhline(pos, color=INK_SOFT, linewidth=1.2, alpha=0.7, zorder=3)\n    ax.axvline(pos, color=INK_SOFT, linewidth=1.2, alpha=0.7, zorder=3)\n\n# Cell annotations — adaptive color: white on deep cells, INK on near-midpoint cells\nfor i in range(n):\n    for j in range(n):\n        val = data[i, j]\n        strong = abs(val) >= 0.6 and i != j\n        text_color = \"white\" if abs(val) > 0.45 else INK\n        ax.text(\n            j,\n            i,\n            f\"{val:.2f}\",\n            ha=\"center\",\n            va=\"center\",\n            fontsize=7 if not strong else 8,\n            fontweight=\"bold\" if strong else \"regular\",\n            color=text_color,\n            zorder=4,\n        )\n\n# Colorbar — narrow, with symmetric padding\ncbar = fig.colorbar(im, ax=ax, fraction=0.032, pad=0.025, aspect=28)\ncbar.ax.tick_params(labelsize=7, colors=INK_SOFT)\ncbar.set_label(\"Correlation\", fontsize=8, color=INK_SOFT, labelpad=8)\ncbar.outline.set_visible(False)\n\n# Title and axis labels\ntitle = \"heatmap-basic · python · matplotlib · anyplot.ai\"\ntitle_fontsize = max(8, round(12 * 67 / len(title))) if len(title) > 67 else 12\nax.set_title(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK, pad=10)\nax.set_xlabel(\"Department\", fontsize=10, color=INK, labelpad=8)\nax.set_ylabel(\"Department\", fontsize=10, color=INK, labelpad=8)\n\nfig.subplots_adjust(left=0.13, right=0.86, top=0.94, bottom=0.16)\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}