{"spec_id":"histogram-2d","library":"altair","language":"python","code":"\"\"\" anyplot.ai\nhistogram-2d: 2D Histogram Heatmap\nLibrary: altair 6.1.0 | Python 3.13.13\nQuality: 82/100 | Updated: 2026-05-08\n\"\"\"\n\nimport os\n\nimport altair as alt\nimport numpy as np\nimport pandas as pd\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\"\n\n# Data: Bivariate normal distribution with correlation\nnp.random.seed(42)\nn_points = 2000\nmean = [0, 0]\ncov = [[1, 0.7], [0.7, 1]]\ndata = np.random.multivariate_normal(mean, cov, n_points)\ndf = pd.DataFrame({\"x\": data[:, 0], \"y\": data[:, 1]})\n\n# Create 2D histogram heatmap using mark_rect with binning\nchart = (\n    alt.Chart(df)\n    .mark_rect()\n    .encode(\n        x=alt.X(\"x:Q\", bin=alt.Bin(maxbins=40), title=\"Variable X\"),\n        y=alt.Y(\"y:Q\", bin=alt.Bin(maxbins=40), title=\"Variable Y\"),\n        color=alt.Color(\n            \"count():Q\",\n            scale=alt.Scale(scheme=\"viridis\"),\n            title=\"Count\",\n            legend=alt.Legend(\n                titleFontSize=18,\n                labelFontSize=16,\n                gradientLength=300,\n                gradientThickness=20,\n                fillColor=ELEVATED_BG,\n                strokeColor=INK_SOFT,\n            ),\n        ),\n        tooltip=[\n            alt.Tooltip(\"x:Q\", format=\".2f\", title=\"X Range\"),\n            alt.Tooltip(\"y:Q\", format=\".2f\", title=\"Y Range\"),\n            alt.Tooltip(\"count():Q\", title=\"Bin Count\"),\n        ],\n    )\n    .properties(\n        width=1600,\n        height=900,\n        title=alt.Title(\"histogram-2d · altair · anyplot.ai\", fontSize=28, anchor=\"middle\"),\n        background=PAGE_BG,\n    )\n    .configure_axis(\n        labelFontSize=18,\n        titleFontSize=22,\n        tickSize=0,\n        domainColor=INK_SOFT,\n        labelColor=INK_SOFT,\n        titleColor=INK,\n        gridColor=INK,\n        gridOpacity=0.0,\n    )\n    .configure_view(fill=PAGE_BG, stroke=INK_SOFT, strokeWidth=1)\n    .configure_title(color=INK, fontSize=28)\n    .configure_legend(fillColor=ELEVATED_BG, strokeColor=INK_SOFT, labelColor=INK_SOFT, titleColor=INK)\n)\n\n# Save as PNG and HTML with theme suffix\nchart.save(f\"plot-{THEME}.png\", scale_factor=3.0)\nchart.save(f\"plot-{THEME}.html\")\n"}