Skip to content

Commit e5da956

Browse files
feat(plotly): implement confusion-matrix (#2284)
## Implementation: `confusion-matrix` - plotly Implements the **plotly** version of `confusion-matrix`. **File:** `plots/confusion-matrix/implementations/plotly.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20526590160)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 8c94072 commit e5da956

2 files changed

Lines changed: 103 additions & 0 deletions

File tree

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
""" pyplots.ai
2+
confusion-matrix: Confusion Matrix Heatmap
3+
Library: plotly 6.5.0 | Python 3.13.11
4+
Quality: 93/100 | Created: 2025-12-26
5+
"""
6+
7+
import numpy as np
8+
import plotly.graph_objects as go
9+
10+
11+
# Data: Multi-class classification results (4 classes - sentiment analysis)
12+
np.random.seed(42)
13+
class_names = ["Negative", "Neutral", "Positive", "Very Positive"]
14+
n_classes = len(class_names)
15+
16+
# Create a realistic confusion matrix with good diagonal but some misclassifications
17+
# Simulating a sentiment classifier that sometimes confuses adjacent classes
18+
confusion_matrix = np.array(
19+
[
20+
[85, 12, 2, 1], # Negative: mostly correct, some confused with Neutral
21+
[8, 72, 15, 5], # Neutral: confused with both adjacent classes
22+
[3, 18, 78, 11], # Positive: some confusion with Neutral and Very Positive
23+
[1, 3, 14, 82], # Very Positive: mostly correct, some confused with Positive
24+
]
25+
)
26+
27+
# Create heatmap
28+
fig = go.Figure(
29+
data=go.Heatmap(
30+
z=confusion_matrix,
31+
x=class_names,
32+
y=class_names,
33+
colorscale="Blues",
34+
showscale=True,
35+
colorbar=dict(title=dict(text="Count", font=dict(size=20)), tickfont=dict(size=16), thickness=25, len=0.8),
36+
hovertemplate="True: %{y}<br>Predicted: %{x}<br>Count: %{z}<extra></extra>",
37+
)
38+
)
39+
40+
# Add text annotations for each cell
41+
annotations = []
42+
for i in range(n_classes):
43+
for j in range(n_classes):
44+
value = confusion_matrix[i, j]
45+
# Use white text on dark backgrounds (high values), black on light
46+
text_color = "white" if value > 50 else "black"
47+
annotations.append(
48+
dict(
49+
x=class_names[j],
50+
y=class_names[i],
51+
text=str(value),
52+
font=dict(size=24, color=text_color),
53+
showarrow=False,
54+
)
55+
)
56+
57+
# Update layout
58+
fig.update_layout(
59+
title=dict(text="confusion-matrix · plotly · pyplots.ai", font=dict(size=28), x=0.5, xanchor="center"),
60+
xaxis=dict(
61+
title=dict(text="Predicted Label", font=dict(size=22)), tickfont=dict(size=18), side="bottom", tickangle=0
62+
),
63+
yaxis=dict(
64+
title=dict(text="True Label", font=dict(size=22)),
65+
tickfont=dict(size=18),
66+
autorange="reversed", # Put first class at top
67+
),
68+
annotations=annotations,
69+
template="plotly_white",
70+
margin=dict(l=120, r=100, t=100, b=100),
71+
)
72+
73+
# Make cells square
74+
fig.update_xaxes(scaleanchor="y", scaleratio=1)
75+
76+
# Save outputs
77+
fig.write_image("plot.png", width=1200, height=1200, scale=3)
78+
fig.write_html("plot.html", include_plotlyjs="cdn")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library: plotly
2+
specification_id: confusion-matrix
3+
created: '2025-12-26T17:36:58Z'
4+
updated: '2025-12-26T17:40:52Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20526590160
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 6.5.0
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/confusion-matrix/plotly/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/confusion-matrix/plotly/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/confusion-matrix/plotly/plot.html
13+
quality_score: 93
14+
review:
15+
strengths:
16+
- Excellent use of Plotly hovertemplate for interactive tooltips showing True/Predicted/Count
17+
- Smart text color contrast logic - white text on dark cells, black text on light
18+
cells
19+
- Square cells using scaleanchor ensures proper matrix visualization
20+
- Clean professional appearance with plotly_white template
21+
- Realistic sentiment analysis data with believable misclassification patterns
22+
weaknesses:
23+
- Image dimensions use square format (3600x3600) instead of standard 4800x2700 landscape,
24+
though appropriate for confusion matrices
25+
- Axis labels could be more descriptive (e.g., True Sentiment Class vs True Label)

0 commit comments

Comments
 (0)