Back to Blog
Blogs 8 min read

How to Plot Confusion Matrix in Python: A Complete Guide

Learn how to create and plot a confusion matrix in Python using scikit-learn and Seaborn so you can evaluate a classification model’s performance.

Himanshu Garg
Himanshu Garg October 22, 2026 3 views
how to plot confusion matrix in python - How to Plot Confusion Matrix in Python: A Complete Guide

Learn how to create and plot a confusion matrix in Python using scikit-learn and Seaborn so you can evaluate a classification model’s performance.

Quick answer

To learn how to plot confusion matrix in Python, you can use scikit-learn’s ConfusionMatrixDisplay. Give it the true labels and the predictions with ConfusionMatrixDisplay.from_predictions(y_true, y_pred). If you need a more customized view, first get the matrix with confusion_matrix(y_true, y_pred) and then plot it with Seaborn’s sns.heatmap(annot=True, fmt='d'). This shows the classification counts in a clear table.

The Role of Confusion Matrices in Model Evaluation

When you build a classification model, understanding how to plot confusion matrix in Python is key to spotting systematic errors. A confusion matrix is a simple table that shows how a supervised learning algorithm performs. It lines up the true class labels with the predicted ones, so you can see not only the overall accuracy but also exactly where the model gets things wrong. Overall accuracy can be very misleading, especially with imbalanced data. For instance, a model that predicts rare system failures might reach 99% accuracy just by always saying no failure occurs.

A confusion matrix reveals this by displaying the counts of True Positives (TP), True Negatives (TN), False Positives (FP), and False Negatives (FN). Plotting the matrix lets you quickly tell if the model has many type I or type II errors, helping you decide how to improve features and tune the model.

For a closely related example, see Train Test Split in Machine Learning Python Example: Avoiding Data Leakage.

Comparison of Python Plotting Methods for Confusion Matrices

Choosing the right plotting library depends on your specific integration requirements, styling needs, and workflow phase.

Factor Engineering view Why it matters
Scikit-learn (ConfusionMatrixDisplay) Fastest implementation, directly integrates with estimators or predictions, automatic labels. Best for rapid model development and validation.
Seaborn (sns.heatmap) Highly customisable, supports complex subplots, custom annotations, and custom styling. Best for production reports and research papers.
Matplotlib (raw imshow) Lowest-level control, requires manual grid, text annotation, and axis alignment setup. Best when avoiding external dependencies beyond matplotlib.

Generating Classification Data and Predictions

Before plotting a confusion matrix, we must train a model and generate predictions on a test dataset. To ensure our evaluation is mathematically sound, we will use scikit-learn to generate a synthetic classification dataset with informative features. We then perform a stratified split to preserve the class ratios in both our training and testing subsets, preventing evaluation bias.

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.ensemble import RandomForestClassifier
# Generate a structured synthetic dataset
X, y = make_classification(
    n_samples=1000,
    n_features=10,
    n_informative=8,
    n_redundant=2,
    random_state=42
)
# Stratified split to maintain class proportions
X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.3, stratify=y, random_state=42
)
# Train a baseline Random Forest classifier
clf = RandomForestClassifier(random_state=42)
clf.fit(X_train, y_train)
# Generate predictions on the test set
y_pred = clf.predict(X_test)

With our true labels (y_test) and predicted labels (y_pred) ready, we can now proceed to explore the different plotting mechanisms available in Python.

For a closely related example, see Rhizosphere 16S rRNA gene amplicon data, PICRUSt2-predicted functional profiles, tuber GC-MS/MS and amino-acid data, plot-level yield and N/C analysis, postharvest storage data, and tuber mineral composition from a potato field trial with an endophytic bacterial consortium..

Plotting with Scikit-Learn ConfusionMatrixDisplay

The cleanest and most direct way to plot a confusion matrix in Python is by using scikit-learn's built-in tool: ConfusionMatrixDisplay. This utility eliminates the need to manually compute the underlying matrix before plotting, reducing the likelihood of indexing or alignment errors.

import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay
# Plot directly from predictions
disp = ConfusionMatrixDisplay.from_predictions(
    y_true=y_test,
    y_pred=y_pred,
    display_labels=["Class A", "Class B"],
    cmap=plt.cm.Blues
)
plt.title("Confusion Matrix via ConfusionMatrixDisplay")
plt.show()

This method automatically handles the colour mapping, axis labels, and text annotations inside each grid square. If you already have a trained estimator instance and your test features, you can also use `ConfusionMatrixDisplay.from_estimator(clf, X_test, y_test)` to achieve the same result in a single step.

Resolving Confusion Matrix Alignment and Code Errors

Use this diagnostic guide to resolve common exceptions and visual bugs when plotting matrices in Python.

  1. 1ValueError: Found input variables with inconsistent numbers of samples
    Verify that y_true and y_pred have identical dimensions. Check if you accidentally passed the training features instead of test features.

    Caused by mismatch in array length.

  2. 2Off-diagonal values swapped or misaligned
    Explicitly define the labels parameter in both the matrix calculation and display function to lock the category order.

    Crucial for non-numeric or multi-class string labels.

  3. 3Overlapping text values in multi-class grids
    Increase the figure size using plt.figure(figsize=(W, H)) before plotting, or rotate the tick labels.

    Common in models with more than 5 classes.

Customising the Plot with Seaborn and Matplotlib

While scikit-learn's native tools are excellent for quick validation, production-grade reports or academic papers often require highly customised styling. For these scenarios, combining the raw `confusion_matrix` calculation with Seaborn's heatmap plotting function offers maximum flexibility.

import seaborn as sns
from sklearn.metrics import confusion_matrix
# Compute the raw numerical confusion matrix
cm = confusion_matrix(y_test, y_pred)
# Set up the matplotlib figure size
plt.figure(figsize=(8, 6))
# Plot the heatmap with specific formatting
sns.heatmap(
    cm, 
    annot=True, 
    fmt="d", 
    cmap="Purples",
    xticklabels=["Class A", "Class B"],
    yticklabels=["Class A", "Class B"]
)
plt.ylabel("Actual Label")
plt.xlabel("Predicted Label")
plt.title("Custom Seaborn Confusion Matrix")
plt.show()

Using Seaborn allows you to easily adjust font sizes, control decimal formatting (via the `fmt` parameter, where 'd' denotes integer formatting), and integrate the plot seamlessly into larger multi-panel figures.

Normalisation and Handling Imbalanced Datasets

When working with imbalanced datasets, absolute numbers in a confusion matrix can obscure poor performance on minority classes. For instance, if Class A has 500 samples and Class B has only 10, a small absolute error of 5 misclassifications in Class B represents a massive 50% failure rate, which might look negligible next to Class A's numbers.
To resolve this, you should normalise the confusion matrix. Normalisation can be performed along the true rows (showing recall), predicted columns (showing precision), or over the entire dataset.

# Plot normalized confusion matrix (row-wise/recall style)
disp_norm = ConfusionMatrixDisplay.from_predictions(
    y_true=y_test,
    y_pred=y_pred,
    display_labels=["Class A", "Class B"],
    cmap=plt.cm.Greens,
    normalize="true",
    values_format=".2f"
)
plt.title("Normalized Confusion Matrix (Recall)")
plt.show()

Setting `normalize='true'` ensures that each row sums to 1.0, making it immediately clear what proportion of each actual class was correctly identified by your machine learning model.

For a closely related example, see How to Improve Machine Learning Model Accuracy: A Systematic MLOps Guide.

Troubleshooting Common Plotting and Alignment Issues

When plotting confusion matrices, developers frequently encounter alignment or dimension mismatches. The most common error is `ValueError: Found input variables with inconsistent numbers of samples`. This occurs when the length of your true labels array does not match the length of your predictions array. Always verify your array shapes using `y_test.shape` and `y_pred.shape` before passing them to the plotting functions. Another frequent issue is label ordering. If your classes are non-numeric or categorical, scikit-learn and Seaborn may order them alphabetically by default, which might not match your logical ordering.

To enforce a specific sequence, use the explicit `labels` parameter in `confusion_matrix(y_test, y_pred, labels=['Class B', 'Class A'])`. This guarantees that your matrix coordinates map correctly to your intended domain logic.

Key takeaways

  • A confusion matrix is essential for diagnosing type I and type II errors, especially on imbalanced datasets.
  • Scikit-learn's ConfusionMatrixDisplay is the fastest, lowest-friction way to generate plots directly from model predictions.
  • Seaborn heatmaps provide the highest level of visual customization for publication-quality figures.
  • Normalising by true labels (row-wise) allows engineers to evaluate class-specific recall rates independently of class size.

Questions engineers often ask

What is the difference between from_predictions and from_estimator in scikit-learn?

ConfusionMatrixDisplay.from_predictions takes precomputed arrays of true and predicted labels directly, making it model-agnostic. ConfusionMatrixDisplay.from_estimator takes the trained model object and the test features, computing the predictions internally before rendering the plot.

How do I plot a confusion matrix for a multi-class classification problem?

The same code works for multi-class classification. Pass your multi-class label and prediction arrays to ConfusionMatrixDisplay.from_predictions. The function automatically scales the grid size to fit the number of unique classes in your dataset.

Why are my confusion matrix labels out of order?

scikit-learn normally arranges class labels in alphabetical and numeric order. If you need a different order, such as putting the negative class before the positive one, provide the plotting function with a list of labels in the order you want, using the labels parameter.

How can I save my plotted confusion matrix to a file?

Before you call plt.show(), use matplotlib’s plt.savefig('filename.png', dpi=300, bbox_inches='tight'). This writes the figure to a PNG file at high resolution and trims away extra blank space.

Continue learning: how to plot confusion matrix in python

For additional practice with how to plot confusion matrix in python, review the example, check your results and explore related technical guidance with Fried Engineers.

Chat with Fried Engineers