A confusion matrix turns held-out classification predictions into a class-by-class count table. In scikit-learn, plotting the matrix makes label mix-ups visible so a classifier review does not depend on accuracy alone.
The ConfusionMatrixDisplay helper can draw the matrix from a fitted estimator or from already computed predictions. Using from_predictions() fits evaluation scripts where y_test and y_pred already exist, and it avoids asking the estimator to predict again.
Keep the label order consistent between the printed matrix, display_labels, and any classification report. Rows represent true labels and columns represent predicted labels, so diagonal cells are correct classifications and off-diagonal cells show the mistakes to review.
Steps to plot a scikit-learn confusion matrix:
- Create confusion_matrix_plot_demo.py with held-out labels, predictions, and a noninteractive Matplotlib backend.
- confusion_matrix_plot_demo.py
from pathlib import Path import matplotlib matplotlib.use("Agg") import matplotlib.pyplot as plt import sklearn from sklearn.datasets import load_wine from sklearn.metrics import ConfusionMatrixDisplay, confusion_matrix from sklearn.model_selection import train_test_split from sklearn.tree import DecisionTreeClassifier wine = load_wine() X_train, X_test, y_train, y_test = train_test_split( wine.data, wine.target, test_size=0.30, stratify=wine.target, random_state=7, ) model = DecisionTreeClassifier(max_depth=3, random_state=7) model.fit(X_train, y_train) y_pred = model.predict(X_test) matrix = confusion_matrix(y_test, y_pred) output_path = Path("confusion-matrix-display.png") fig, ax = plt.subplots(figsize=(6, 5)) ConfusionMatrixDisplay.from_predictions( y_test, y_pred, display_labels=wine.target_names, values_format="d", cmap="Blues", colorbar=False, ax=ax, ) ax.set_title("Wine classifier confusion matrix") fig.tight_layout() fig.savefig(output_path, dpi=160, bbox_inches="tight") print(f"scikit-learn {sklearn.__version__}") print("labels: " + ", ".join(wine.target_names)) print("confusion matrix:") print(matrix) print(f"saved plot: {output_path}")
matplotlib.use(“Agg”) saves the plot from a shell, container, or job runner that does not have an interactive display.
- Run the plotting script.
$ python3 confusion_matrix_plot_demo.py scikit-learn 1.9.0 labels: class_0, class_1, class_2 confusion matrix: [[15 3 0] [ 0 20 1] [ 0 0 15]] saved plot: confusion-matrix-display.png
- Check the off-diagonal counts before accepting the plot.
The class_0 row shows 3 samples predicted as class_1, and the class_1 row shows 1 sample predicted as class_2. The diagonal cells show 15, 20, and 15 correct predictions.
- Open the saved PNG and confirm that the labels and counts match the printed matrix.
Fix display_labels or pass an explicit labels order before sharing the plot if the class names do not match the matrix order.
Mohd Shakir Zakaria is a cloud architect with deep roots in software development and open-source advocacy. Certified in AWS, Red Hat, VMware, ITIL, and Linux, he specializes in designing and managing robust cloud and on-premises infrastructures.