{"spec_id":"heatmap-clustered","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nheatmap-clustered: Clustered Heatmap\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 78/100 | Updated: 2026-05-09\n\"\"\"\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom scipy.cluster.hierarchy import dendrogram, linkage\nfrom scipy.spatial.distance import pdist\n\n\n# Data - Gene expression analysis (15 genes x 12 samples)\nnp.random.seed(42)\n\n# Create realistic gene expression data with natural clusters\nn_genes = 15\nn_samples = 12\n\n# Gene names (cell cycle, metabolism, immune response clusters)\ngene_names = [\n    \"CDK1\",\n    \"CCNB1\",\n    \"PLK1\",\n    \"AURKA\",\n    \"BUB1\",  # Cell cycle genes\n    \"GAPDH\",\n    \"LDHA\",\n    \"PKM\",\n    \"HK2\",\n    \"ENO1\",  # Metabolism genes\n    \"IL6\",\n    \"TNF\",\n    \"IFNG\",\n    \"IL1B\",\n    \"CXCL8\",  # Immune response genes\n]\n\n# Sample names (tumor vs normal, 3 replicates each)\nsample_names = [\n    \"T1_A\",\n    \"T1_B\",\n    \"T1_C\",\n    \"T2_A\",\n    \"T2_B\",\n    \"T2_C\",  # Tumor samples\n    \"N1_A\",\n    \"N1_B\",\n    \"N1_C\",\n    \"N2_A\",\n    \"N2_B\",\n    \"N2_C\",  # Normal samples\n]\n\n# Generate expression data with cluster structure\ndata = np.random.randn(n_genes, n_samples) * 0.5\n\n# Cell cycle genes upregulated in tumors\ndata[0:5, 0:6] += 2.0\ndata[0:5, 6:12] -= 1.5\n\n# Metabolism genes moderately upregulated in tumors\ndata[5:10, 0:6] += 1.0\ndata[5:10, 6:12] -= 0.5\n\n# Immune genes show mixed pattern\ndata[10:15, 0:3] += 1.5\ndata[10:15, 3:6] -= 0.5\ndata[10:15, 6:9] += 0.8\ndata[10:15, 9:12] -= 1.0\n\n# Perform hierarchical clustering\nrow_linkage = linkage(pdist(data, metric=\"euclidean\"), method=\"ward\")\ncol_linkage = linkage(pdist(data.T, metric=\"euclidean\"), method=\"ward\")\n\n# Get ordering from clustering\nrow_order = dendrogram(row_linkage, no_plot=True)[\"leaves\"]\ncol_order = dendrogram(col_linkage, no_plot=True)[\"leaves\"]\n\n# Reorder data and labels\ndata_clustered = data[row_order, :][:, col_order]\ngene_names_ordered = [gene_names[i] for i in row_order]\nsample_names_ordered = [sample_names[i] for i in col_order]\n\n# Create figure with gridspec for dendrograms and heatmap\nfig = plt.figure(figsize=(16, 12))\n\n# Define grid: column dendrogram, row dendrogram, heatmap, colorbar\ngs = fig.add_gridspec(2, 3, width_ratios=[0.15, 1, 0.05], height_ratios=[0.15, 1], wspace=0.02, hspace=0.02)\n\n# Column dendrogram (top)\nax_col_dendrogram = fig.add_subplot(gs[0, 1])\ndendrogram(col_linkage, ax=ax_col_dendrogram, color_threshold=0, above_threshold_color=\"#306998\")\nax_col_dendrogram.set_xticks([])\nax_col_dendrogram.set_yticks([])\nax_col_dendrogram.spines[\"top\"].set_visible(False)\nax_col_dendrogram.spines[\"right\"].set_visible(False)\nax_col_dendrogram.spines[\"bottom\"].set_visible(False)\nax_col_dendrogram.spines[\"left\"].set_visible(False)\n\n# Row dendrogram (left)\nax_row_dendrogram = fig.add_subplot(gs[1, 0])\ndendrogram(row_linkage, ax=ax_row_dendrogram, orientation=\"left\", color_threshold=0, above_threshold_color=\"#306998\")\nax_row_dendrogram.set_xticks([])\nax_row_dendrogram.set_yticks([])\nax_row_dendrogram.spines[\"top\"].set_visible(False)\nax_row_dendrogram.spines[\"right\"].set_visible(False)\nax_row_dendrogram.spines[\"bottom\"].set_visible(False)\nax_row_dendrogram.spines[\"left\"].set_visible(False)\n\n# Heatmap (center)\nax_heatmap = fig.add_subplot(gs[1, 1])\nvmax = np.abs(data_clustered).max()\nim = ax_heatmap.imshow(data_clustered, cmap=\"RdBu_r\", aspect=\"auto\", vmin=-vmax, vmax=vmax)\n\n# Configure heatmap axes\nax_heatmap.set_xticks(np.arange(n_samples))\nax_heatmap.set_xticklabels(sample_names_ordered, fontsize=14, rotation=45, ha=\"right\")\nax_heatmap.set_yticks(np.arange(n_genes))\nax_heatmap.set_yticklabels(gene_names_ordered, fontsize=14)\nax_heatmap.tick_params(axis=\"both\", length=0)\n\n# Colorbar\nax_colorbar = fig.add_subplot(gs[1, 2])\ncbar = plt.colorbar(im, cax=ax_colorbar)\ncbar.set_label(\"Expression (z-score)\", fontsize=16)\ncbar.ax.tick_params(labelsize=14)\n\n# Title\nfig.suptitle(\"heatmap-clustered · matplotlib · pyplots.ai\", fontsize=24, y=0.98)\n\nplt.savefig(\"plot.png\", dpi=300, bbox_inches=\"tight\", facecolor=\"white\")\n"}