{"spec_id":"confusion-matrix","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nconfusion-matrix: Confusion Matrix Heatmap\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-05-09\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport plotly.graph_objects as go\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\"\nGRID = \"rgba(26,26,23,0.10)\" if THEME == \"light\" else \"rgba(240,239,232,0.10)\"\n\n# Data: Multi-class product quality classification (5 classes)\nnp.random.seed(42)\nclass_names = [\"Defective\", \"Poor\", \"Average\", \"Good\", \"Excellent\"]\nn_classes = len(class_names)\n\n# Create realistic confusion matrix for product quality classification\n# A model that generally predicts well but sometimes confuses adjacent quality levels\nconfusion_matrix = np.array(\n    [\n        [92, 6, 1, 1, 0],  # Defective: almost always caught correctly\n        [5, 78, 12, 4, 1],  # Poor: some confusion with Average\n        [2, 14, 71, 10, 3],  # Average: scattered confusion across range\n        [1, 5, 13, 75, 6],  # Good: mostly correct, some confused with Average/Excellent\n        [0, 1, 4, 8, 87],  # Excellent: very reliable classification\n    ]\n)\n\n# Create heatmap with theme-adaptive colors\nfig = go.Figure(\n    data=go.Heatmap(\n        z=confusion_matrix,\n        x=class_names,\n        y=class_names,\n        colorscale=\"Blues\",\n        showscale=True,\n        colorbar=dict(\n            title=dict(text=\"Count\", font=dict(size=20, color=INK)),\n            tickfont=dict(size=16, color=INK_SOFT),\n            thickness=25,\n            len=0.8,\n            tickcolor=INK_SOFT,\n        ),\n        hovertemplate=\"True: %{y}<br>Predicted: %{x}<br>Count: %{z}<extra></extra>\",\n    )\n)\n\n# Add text annotations with theme-adaptive text color\nannotations = []\nfor i in range(n_classes):\n    for j in range(n_classes):\n        value = confusion_matrix[i, j]\n        text_color = \"white\" if value > 50 else INK_SOFT\n        annotations.append(\n            dict(\n                x=class_names[j],\n                y=class_names[i],\n                text=str(value),\n                font=dict(size=24, color=text_color),\n                showarrow=False,\n            )\n        )\n\n# Update layout with theme-adaptive styling\nfig.update_layout(\n    title=dict(text=\"confusion-matrix · plotly · anyplot.ai\", font=dict(size=28, color=INK), x=0.5, xanchor=\"center\"),\n    xaxis=dict(\n        title=dict(text=\"Predicted Class\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        side=\"bottom\",\n        tickangle=0,\n        showgrid=False,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    yaxis=dict(\n        title=dict(text=\"True Class\", font=dict(size=22, color=INK)),\n        tickfont=dict(size=18, color=INK_SOFT),\n        autorange=\"reversed\",\n        showgrid=False,\n        linecolor=INK_SOFT,\n        zerolinecolor=INK_SOFT,\n    ),\n    annotations=annotations,\n    paper_bgcolor=PAGE_BG,\n    plot_bgcolor=PAGE_BG,\n    margin=dict(l=140, r=120, t=120, b=120),\n    font=dict(family=\"Arial, sans-serif\", color=INK),\n)\n\n# Make cells square\nfig.update_xaxes(scaleanchor=\"y\", scaleratio=1)\n\n# Save outputs\nfig.write_image(f\"plot-{THEME}.png\", width=1600, height=900, scale=3)\nfig.write_html(f\"plot-{THEME}.html\", include_plotlyjs=\"cdn\")\n"}