{"spec_id":"heatmap-correlation","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nheatmap-correlation: Correlation Matrix Heatmap\nLibrary: altair 6.2.2 | Python 3.13.15\nQuality: 92/100 | Updated: 2026-08-18\n\"\"\"\n\nimport os\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\nfrom PIL import Image\n\n\n# Theme tokens (Imprint palette — theme-adaptive chrome)\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\"\n\n# Data - realistic financial metrics correlation matrix\nnp.random.seed(42)\n\nvariables = [\"Revenue\", \"Profit\", \"Expenses\", \"Employees\", \"Market Cap\", \"Debt\", \"Assets\", \"R&D Spend\"]\nn = len(variables)\n\n# Latent-factor model (\"company scale\", \"profitability\", \"leverage\") so relationships\n# read as economically sensible: bigger companies have more Revenue/Expenses/Employees/\n# Assets (scale factor), Profit tracks Market Cap (profitability factor), and Debt scales\n# with leverage independent of profitability.\nloadings = np.array(\n    [\n        [0.82, 0.15, 0.00],  # Revenue\n        [0.20, 0.85, -0.10],  # Profit\n        [0.84, -0.15, 0.05],  # Expenses\n        [0.65, 0.05, 0.00],  # Employees\n        [0.35, 0.82, -0.10],  # Market Cap\n        [0.30, -0.30, 0.78],  # Debt\n        [0.72, 0.10, 0.42],  # Assets\n        [0.42, 0.15, 0.00],  # R&D Spend\n    ]\n)\nidiosyncratic = np.diag(0.30 + 0.15 * np.random.rand(n))\ncovariance = loadings @ loadings.T + idiosyncratic\nD = np.sqrt(np.diag(covariance))\ncorrelation = covariance / np.outer(D, D)\nnp.fill_diagonal(correlation, 1.0)\ncorrelation = np.round(correlation, 2)\n\n# Convert to long format for Altair, masking the upper triangle to avoid redundancy\nrows = [\n    {\"Variable 1\": variables[i], \"Variable 2\": variables[j], \"Correlation\": correlation[i, j]}\n    for i in range(n)\n    for j in range(n)\n    if i >= j\n]\ndf = pd.DataFrame(rows)\n\n# Highlight strong correlations (|r| > 0.6) with an ink outline for visual hierarchy\nstrong = (alt.datum.Correlation > 0.6) | (alt.datum.Correlation < -0.6)\n\ntitle = \"heatmap-correlation · python · altair · anyplot.ai\"\ntitle_fontsize = round(16 * (67 / len(title) if len(title) > 67 else 1.0))\n\nbase = alt.Chart(df).encode(\n    x=alt.X(\n        \"Variable 1:N\",\n        title=\"Financial Metrics\",\n        sort=variables,\n        axis=alt.Axis(\n            labelAngle=-40,\n            labelFontSize=11,\n            labelColor=INK_SOFT,\n            titleColor=INK,\n            titleFontSize=13,\n            titleFontWeight=\"bold\",\n            grid=False,\n        ),\n    ),\n    y=alt.Y(\n        \"Variable 2:N\",\n        title=\"Financial Metrics\",\n        sort=variables,\n        axis=alt.Axis(\n            labelFontSize=11, labelColor=INK_SOFT, titleColor=INK, titleFontSize=13, titleFontWeight=\"bold\", grid=False\n        ),\n    ),\n)\n\n# Heatmap cells: Imprint diverging colormap centered on zero, fixed -1..1 domain\nheatmap = base.mark_rect().encode(\n    color=alt.Color(\n        \"Correlation:Q\",\n        scale=alt.Scale(domain=[-1, 1], range=[\"#AE3030\", PAGE_BG, \"#4467A3\"], domainMid=0),\n        legend=alt.Legend(\n            title=\"Correlation\",\n            titleFontSize=13,\n            titleColor=INK,\n            labelFontSize=12,\n            labelColor=INK_SOFT,\n            gradientLength=180,\n            gradientThickness=14,\n            fillColor=ELEVATED_BG,\n            strokeColor=INK_SOFT,\n        ),\n    ),\n    stroke=alt.condition(strong, alt.value(INK), alt.value(PAGE_BG)),\n    strokeWidth=alt.condition(strong, alt.value(2.5), alt.value(1)),\n    tooltip=[\n        alt.Tooltip(\"Variable 1:N\", title=\"X Variable\"),\n        alt.Tooltip(\"Variable 2:N\", title=\"Y Variable\"),\n        alt.Tooltip(\"Correlation:Q\", title=\"Correlation\", format=\".3f\"),\n    ],\n)\n\n# Correlation value annotations, with contrast-aware text color per cell\ntext = base.mark_text(fontSize=12, fontWeight=\"bold\").encode(\n    text=alt.Text(\"Correlation:Q\", format=\".2f\"), color=alt.condition(strong, alt.value(PAGE_BG), alt.value(INK))\n)\n\nchart = (\n    (heatmap + text)\n    .properties(\n        background=PAGE_BG,\n        width=412,\n        height=460,\n        title=alt.Title(title, fontSize=title_fontsize, fontWeight=\"bold\", anchor=\"middle\", color=INK),\n    )\n    .configure_view(fill=PAGE_BG, stroke=INK_SOFT, continuousWidth=412, continuousHeight=460)\n)\n\n# Hard target: 2400 x 2400 (square). See prompts/library/altair.md \"Canvas\".\nchart.save(f\"plot-{THEME}.png\", scale_factor=4.0)\n\nTW, TH = 2400, 2400\n_img = Image.open(f\"plot-{THEME}.png\").convert(\"RGB\")\n_w, _h = _img.size\nif _w > TW or _h > TH:\n    raise SystemExit(\n        f\"altair vl-convert produced {_w}x{_h}, exceeds target {TW}x{TH}. \"\n        f\"Shrink chart .properties(width=, height=) values and re-render.\"\n    )\nif _w < TW or _h < TH:\n    _canvas = Image.new(\"RGB\", (TW, TH), PAGE_BG)\n    _canvas.paste(_img, ((TW - _w) // 2, (TH - _h) // 2))\n    _canvas.save(f\"plot-{THEME}.png\")\n\nchart.save(f\"plot-{THEME}.html\")\n"}