{"spec_id":"heatmap-annotated","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nheatmap-annotated: Annotated Heatmap\nLibrary: plotnine 0.15.7 | Python 3.13.14\nQuality: 91/100 | Updated: 2026-08-05\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    coord_fixed,\n    element_blank,\n    element_rect,\n    element_text,\n    geom_text,\n    geom_tile,\n    ggplot,\n    labs,\n    scale_color_identity,\n    scale_fill_gradient2,\n    theme,\n    theme_minimal,\n)\n\n\n# Theme tokens (see prompts/default-style-guide.md \"Theme-adaptive Chrome\")\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\"\nTEXT_ON_SATURATED = \"#F0EFE8\"  # readable text over saturated red/blue cells in either theme\n\n# Data: Correlation matrix of economic indicators\nnp.random.seed(42)\nvariables = [\n    \"GDP Growth\",\n    \"Inflation\",\n    \"Unemployment\",\n    \"Interest Rate\",\n    \"Consumer Conf\",\n    \"Mfg Index\",\n    \"Export Vol\",\n    \"Housing\",\n]\n\nn_vars = len(variables)\n\n# Generate a realistic correlation matrix\nbase = np.random.randn(n_vars, n_vars)\ncorr_matrix = np.dot(base, base.T)\nd = np.sqrt(np.diag(corr_matrix))\ncorr_matrix = corr_matrix / d[:, None] / d[None, :]\nnp.fill_diagonal(corr_matrix, 1.0)\ncorr_matrix = (corr_matrix + corr_matrix.T) / 2  # Ensure symmetry\n\n# Create DataFrame in long format for plotnine\nrows = []\nfor i, row_var in enumerate(variables):\n    for j, col_var in enumerate(variables):\n        rows.append({\"x\": col_var, \"y\": row_var, \"value\": corr_matrix[i, j]})\n\ndf = pd.DataFrame(rows)\n\n# Convert to categorical to preserve order\ndf[\"x\"] = pd.Categorical(df[\"x\"], categories=variables, ordered=True)\ndf[\"y\"] = pd.Categorical(df[\"y\"], categories=variables[::-1], ordered=True)\n\n# Text color must contrast with its own cell: saturated cells get light text,\n# near-neutral (midpoint) cells get the theme's own ink color.\ndf[\"text_color\"] = np.where(df[\"value\"].abs() > 0.5, TEXT_ON_SATURATED, INK)\n\n# Title — length-scaled per prompts/plot-generator.md \"Title fontsize must scale with title length\"\ntitle = \"heatmap-annotated · python · plotnine · anyplot.ai\"\ntitle_fontsize = round(12 * min(1.0, 67 / len(title)))\n\n# Create the annotated heatmap using the Imprint diverging colormap (imprint_div)\nplot = (\n    ggplot(df, aes(x=\"x\", y=\"y\", fill=\"value\"))\n    + geom_tile(color=PAGE_BG, size=0.6)\n    + geom_text(aes(label=\"value\", color=\"text_color\"), format_string=\"{:.2f}\", size=3.5)\n    + scale_fill_gradient2(low=\"#AE3030\", mid=PAGE_BG, high=\"#4467A3\", midpoint=0, limits=(-1, 1), name=\"Correlation\")\n    + scale_color_identity()\n    + labs(x=\"Economic Indicator\", y=\"Economic Indicator\", title=title)\n    + coord_fixed(ratio=1)\n    + theme_minimal()\n    + theme(\n        figure_size=(6, 6),\n        plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        panel_background=element_rect(fill=PAGE_BG),\n        panel_grid_major=element_blank(),\n        panel_grid_minor=element_blank(),\n        panel_border=element_blank(),\n        plot_title=element_text(size=title_fontsize, color=INK, ha=\"center\"),\n        axis_title=element_text(size=10, color=INK),\n        axis_text_x=element_text(size=8, color=INK_SOFT, rotation=45, ha=\"right\"),\n        axis_text_y=element_text(size=8, color=INK_SOFT),\n        axis_ticks=element_blank(),\n        legend_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n        legend_title=element_text(size=10, color=INK),\n        legend_text=element_text(size=8, color=INK_SOFT),\n    )\n)\n\n# Save\nplot.save(f\"plot-{THEME}.png\", dpi=400, width=6, height=6, units=\"in\")\n"}