Skip to content

Commit d2db30b

Browse files
feat(seaborn): implement precision-recall (#2326)
## Implementation: `precision-recall` - seaborn Implements the **seaborn** version of `precision-recall`. **File:** `plots/precision-recall/implementations/seaborn.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20527869532)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 1603fc0 commit d2db30b

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
""" pyplots.ai
2+
precision-recall: Precision-Recall Curve
3+
Library: seaborn 0.13.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-26
5+
"""
6+
7+
import matplotlib.pyplot as plt
8+
import numpy as np
9+
import seaborn as sns
10+
from sklearn.metrics import average_precision_score, precision_recall_curve
11+
12+
13+
# Data - Simulate binary classification with imbalanced classes (fraud detection scenario)
14+
np.random.seed(42)
15+
n_samples = 1000
16+
n_positive = 100 # 10% positive class (imbalanced)
17+
18+
# Ground truth labels
19+
y_true = np.zeros(n_samples)
20+
y_true[:n_positive] = 1
21+
np.random.shuffle(y_true)
22+
23+
# Simulate classifier scores - better separation for positives
24+
y_scores_good = np.where(
25+
y_true == 1,
26+
np.random.beta(5, 2, n_samples), # Positives: higher scores
27+
np.random.beta(2, 5, n_samples), # Negatives: lower scores
28+
)
29+
30+
y_scores_moderate = np.where(
31+
y_true == 1,
32+
np.random.beta(3, 2, n_samples), # Positives: moderately higher
33+
np.random.beta(2, 3, n_samples), # Negatives: moderately lower
34+
)
35+
36+
# Calculate precision-recall curves
37+
precision_good, recall_good, _ = precision_recall_curve(y_true, y_scores_good)
38+
precision_moderate, recall_moderate, _ = precision_recall_curve(y_true, y_scores_moderate)
39+
40+
# Average precision scores
41+
ap_good = average_precision_score(y_true, y_scores_good)
42+
ap_moderate = average_precision_score(y_true, y_scores_moderate)
43+
44+
# Baseline (random classifier)
45+
baseline = n_positive / n_samples
46+
47+
# Create plot
48+
fig, ax = plt.subplots(figsize=(16, 9))
49+
sns.set_style("whitegrid")
50+
51+
# Plot PR curves using seaborn's lineplot style with step interpolation
52+
# Good classifier
53+
ax.step(recall_good, precision_good, where="post", linewidth=3, color="#306998", label=f"Model A (AP = {ap_good:.2f})")
54+
ax.fill_between(recall_good, precision_good, step="post", alpha=0.2, color="#306998")
55+
56+
# Moderate classifier
57+
ax.step(
58+
recall_moderate,
59+
precision_moderate,
60+
where="post",
61+
linewidth=3,
62+
color="#FFD43B",
63+
label=f"Model B (AP = {ap_moderate:.2f})",
64+
)
65+
ax.fill_between(recall_moderate, precision_moderate, step="post", alpha=0.2, color="#FFD43B")
66+
67+
# Baseline reference line
68+
ax.axhline(y=baseline, linestyle="--", linewidth=2, color="#888888", label=f"Random Classifier (P = {baseline:.2f})")
69+
70+
# Styling with seaborn aesthetics
71+
ax.set_xlabel("Recall (Sensitivity)", fontsize=20)
72+
ax.set_ylabel("Precision (Positive Predictive Value)", fontsize=20)
73+
ax.set_title("precision-recall · seaborn · pyplots.ai", fontsize=24)
74+
ax.tick_params(axis="both", labelsize=16)
75+
76+
# Set axis limits
77+
ax.set_xlim([0.0, 1.0])
78+
ax.set_ylim([0.0, 1.05])
79+
80+
# Legend
81+
ax.legend(loc="upper right", fontsize=16, frameon=True, fancybox=True, framealpha=0.9, edgecolor="#cccccc")
82+
83+
# Grid styling
84+
ax.grid(True, alpha=0.3, linestyle="--")
85+
86+
plt.tight_layout()
87+
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
library: seaborn
2+
specification_id: precision-recall
3+
created: '2025-12-26T19:11:19Z'
4+
updated: '2025-12-26T19:13:34Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20527869532
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 0.13.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/precision-recall/seaborn/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/precision-recall/seaborn/plot_thumb.png
12+
preview_html: null
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent visual clarity with properly sized fonts and stepped line visualization
17+
- Well-implemented comparison of two classifiers with different performance levels
18+
- Baseline reference line clearly shows random classifier performance at the positive
19+
class ratio
20+
- Realistic fraud detection scenario with appropriate 10% class imbalance
21+
- Good use of fill_between to show area under curves, enhancing visual distinction
22+
- Clean, maintainable code following KISS principles
23+
weaknesses:
24+
- Limited use of seaborn-specific features; primarily uses matplotlib drawing functions
25+
- Could benefit from a third classifier curve to show fuller performance spectrum
26+
(poor performer)

0 commit comments

Comments
 (0)