From 66ad20200422ddf72261aaa847b6ee467e43012a Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 26 Dec 2025 19:37:45 +0000 Subject: [PATCH 1/3] feat(matplotlib): implement calibration-curve --- .../implementations/matplotlib.py | 118 ++++++++++++++++++ 1 file changed, 118 insertions(+) create mode 100644 plots/calibration-curve/implementations/matplotlib.py diff --git a/plots/calibration-curve/implementations/matplotlib.py b/plots/calibration-curve/implementations/matplotlib.py new file mode 100644 index 0000000000..ac1b0564d1 --- /dev/null +++ b/plots/calibration-curve/implementations/matplotlib.py @@ -0,0 +1,118 @@ +"""pyplots.ai +calibration-curve: Calibration Curve +Library: matplotlib | Python 3.13 +Quality: pending | Created: 2025-12-26 +""" + +import matplotlib.pyplot as plt +import numpy as np + + +# Data: Simulate predictions from classifiers with different calibration properties +np.random.seed(42) +n_samples = 2000 +n_bins = 10 + +# Generate ground truth - imbalanced to be realistic (35% positive rate) +y_true = np.random.binomial(1, 0.35, n_samples) + +# Well-calibrated model: predictions closely match true probability +# Using logistic transformation with moderate noise +logits_calibrated = 1.2 * (y_true * 2 - 1) + np.random.normal(0, 1.0, n_samples) +y_prob_calibrated = 1 / (1 + np.exp(-logits_calibrated)) + +# Overconfident model: pushes predictions toward 0 and 1 (sigmoid with steeper slope) +logits_over = 2.0 * (y_true * 2 - 1) + np.random.normal(0, 0.5, n_samples) +y_prob_overconfident = 1 / (1 + np.exp(-logits_over)) + +# Underconfident model: predictions clustered toward 0.5 (flatter sigmoid) +logits_under = 0.5 * (y_true * 2 - 1) + np.random.normal(0, 0.8, n_samples) +y_prob_underconfident = 1 / (1 + np.exp(-logits_under)) + +# Calculate calibration curves for each model +bin_edges = np.linspace(0, 1, n_bins + 1) + +# Well-calibrated model calibration curve +bin_idx_cal = np.digitize(y_prob_calibrated, bin_edges[1:-1]) +prob_true_cal = [np.mean(y_true[bin_idx_cal == i]) for i in range(n_bins) if np.sum(bin_idx_cal == i) > 0] +prob_pred_cal = [np.mean(y_prob_calibrated[bin_idx_cal == i]) for i in range(n_bins) if np.sum(bin_idx_cal == i) > 0] + +# Overconfident model calibration curve +bin_idx_over = np.digitize(y_prob_overconfident, bin_edges[1:-1]) +prob_true_over = [np.mean(y_true[bin_idx_over == i]) for i in range(n_bins) if np.sum(bin_idx_over == i) > 0] +prob_pred_over = [ + np.mean(y_prob_overconfident[bin_idx_over == i]) for i in range(n_bins) if np.sum(bin_idx_over == i) > 0 +] + +# Underconfident model calibration curve +bin_idx_under = np.digitize(y_prob_underconfident, bin_edges[1:-1]) +prob_true_under = [np.mean(y_true[bin_idx_under == i]) for i in range(n_bins) if np.sum(bin_idx_under == i) > 0] +prob_pred_under = [ + np.mean(y_prob_underconfident[bin_idx_under == i]) for i in range(n_bins) if np.sum(bin_idx_under == i) > 0 +] + +# Calculate Brier scores (mean squared error of probability predictions) +brier_cal = np.mean((y_prob_calibrated - y_true) ** 2) +brier_over = np.mean((y_prob_overconfident - y_true) ** 2) +brier_under = np.mean((y_prob_underconfident - y_true) ** 2) + +# Create figure with two subplots: calibration curve and histogram +fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(16, 9), gridspec_kw={"height_ratios": [3, 1]}) + +# Primary colors from style guide +python_blue = "#306998" +python_yellow = "#FFD43B" +third_color = "#E377C2" # Colorblind-safe pink/magenta + +# Plot calibration curves +ax1.plot([0, 1], [0, 1], "k--", linewidth=2, label="Perfect Calibration", alpha=0.7) +ax1.plot( + prob_pred_cal, + prob_true_cal, + "o-", + color=python_blue, + linewidth=3, + markersize=12, + label=f"Well-Calibrated (Brier: {brier_cal:.3f})", +) +ax1.plot( + prob_pred_over, + prob_true_over, + "s-", + color=python_yellow, + linewidth=3, + markersize=12, + label=f"Overconfident (Brier: {brier_over:.3f})", +) +ax1.plot( + prob_pred_under, + prob_true_under, + "^-", + color=third_color, + linewidth=3, + markersize=12, + label=f"Underconfident (Brier: {brier_under:.3f})", +) + +# Style calibration plot +ax1.set_xlabel("Mean Predicted Probability", fontsize=20) +ax1.set_ylabel("Fraction of Positives", fontsize=20) +ax1.set_title("calibration-curve · matplotlib · pyplots.ai", fontsize=24) +ax1.tick_params(axis="both", labelsize=16) +ax1.legend(fontsize=16, loc="lower right") +ax1.grid(True, alpha=0.3, linestyle="--") +ax1.set_xlim(0, 1) +ax1.set_ylim(0, 1) + +# Histogram of predicted probabilities +ax2.hist(y_prob_calibrated, bins=20, alpha=0.6, color=python_blue, label="Well-Calibrated", edgecolor="white") +ax2.hist(y_prob_overconfident, bins=20, alpha=0.6, color=python_yellow, label="Overconfident", edgecolor="white") +ax2.hist(y_prob_underconfident, bins=20, alpha=0.6, color=third_color, label="Underconfident", edgecolor="white") +ax2.set_xlabel("Predicted Probability", fontsize=20) +ax2.set_ylabel("Count", fontsize=20) +ax2.tick_params(axis="both", labelsize=16) +ax2.legend(fontsize=14, loc="upper right") +ax2.grid(True, alpha=0.3, linestyle="--") + +plt.tight_layout() +plt.savefig("plot.png", dpi=300, bbox_inches="tight") From cc1a6fe5cac139aa814bbb22c4e1b6d25c0f21f7 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 26 Dec 2025 19:38:05 +0000 Subject: [PATCH 2/3] chore(matplotlib): add metadata for calibration-curve --- .../metadata/matplotlib.yaml | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 plots/calibration-curve/metadata/matplotlib.yaml diff --git a/plots/calibration-curve/metadata/matplotlib.yaml b/plots/calibration-curve/metadata/matplotlib.yaml new file mode 100644 index 0000000000..17191bb0b4 --- /dev/null +++ b/plots/calibration-curve/metadata/matplotlib.yaml @@ -0,0 +1,19 @@ +# Per-library metadata for matplotlib implementation of calibration-curve +# Auto-generated by impl-generate.yml + +library: matplotlib +specification_id: calibration-curve +created: '2025-12-26T19:38:04Z' +updated: '2025-12-26T19:38:04Z' +generated_by: claude-opus-4-5-20251101 +workflow_run: 20528201914 +issue: 0 +python_version: 3.13.11 +library_version: 3.10.8 +preview_url: https://storage.googleapis.com/pyplots-images/plots/calibration-curve/matplotlib/plot.png +preview_thumb: https://storage.googleapis.com/pyplots-images/plots/calibration-curve/matplotlib/plot_thumb.png +preview_html: null +quality_score: null +review: + strengths: [] + weaknesses: [] From afb357a88404b9831c438241890e84417c4418dd Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" Date: Fri, 26 Dec 2025 19:44:39 +0000 Subject: [PATCH 3/3] chore(matplotlib): update quality score 93 and review feedback for calibration-curve --- .../implementations/matplotlib.py | 6 +++--- .../metadata/matplotlib.yaml | 21 ++++++++++++------- 2 files changed, 17 insertions(+), 10 deletions(-) diff --git a/plots/calibration-curve/implementations/matplotlib.py b/plots/calibration-curve/implementations/matplotlib.py index ac1b0564d1..bfcb8af73f 100644 --- a/plots/calibration-curve/implementations/matplotlib.py +++ b/plots/calibration-curve/implementations/matplotlib.py @@ -1,7 +1,7 @@ -"""pyplots.ai +""" pyplots.ai calibration-curve: Calibration Curve -Library: matplotlib | Python 3.13 -Quality: pending | Created: 2025-12-26 +Library: matplotlib 3.10.8 | Python 3.13.11 +Quality: 93/100 | Created: 2025-12-26 """ import matplotlib.pyplot as plt diff --git a/plots/calibration-curve/metadata/matplotlib.yaml b/plots/calibration-curve/metadata/matplotlib.yaml index 17191bb0b4..e139f88dd8 100644 --- a/plots/calibration-curve/metadata/matplotlib.yaml +++ b/plots/calibration-curve/metadata/matplotlib.yaml @@ -1,10 +1,7 @@ -# Per-library metadata for matplotlib implementation of calibration-curve -# Auto-generated by impl-generate.yml - library: matplotlib specification_id: calibration-curve created: '2025-12-26T19:38:04Z' -updated: '2025-12-26T19:38:04Z' +updated: '2025-12-26T19:44:38Z' generated_by: claude-opus-4-5-20251101 workflow_run: 20528201914 issue: 0 @@ -13,7 +10,17 @@ library_version: 3.10.8 preview_url: https://storage.googleapis.com/pyplots-images/plots/calibration-curve/matplotlib/plot.png preview_thumb: https://storage.googleapis.com/pyplots-images/plots/calibration-curve/matplotlib/plot_thumb.png preview_html: null -quality_score: null +quality_score: 93 review: - strengths: [] - weaknesses: [] + strengths: + - Excellent multi-model comparison showing well-calibrated, overconfident, and underconfident + classifiers + - Includes histogram subplot as suggested in spec for showing prediction distributions + - Brier scores integrated into legend for quick comparison + - Clean separation of calibration curve calculation logic + - Colorblind-friendly palette with distinct marker shapes for each model + - Professional layout with appropriate subplot height ratios + weaknesses: + - Axis labels lack units or additional context + - Could use more distinctive matplotlib features like fill_between for confidence + bands