Skip to content

Commit 99c5d76

Browse files
feat(plotnine): implement roc-curve (#2299)
## Implementation: `roc-curve` - plotnine Implements the **plotnine** version of `roc-curve`. **File:** `plots/roc-curve/implementations/plotnine.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20526595151)* --------- 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 f071ade commit 99c5d76

2 files changed

Lines changed: 110 additions & 0 deletions

File tree

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
""" pyplots.ai
2+
roc-curve: ROC Curve with AUC
3+
Library: plotnine 0.15.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-26
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
from plotnine import (
10+
aes,
11+
annotate,
12+
coord_fixed,
13+
element_line,
14+
element_text,
15+
geom_abline,
16+
geom_line,
17+
ggplot,
18+
labs,
19+
scale_color_manual,
20+
scale_x_continuous,
21+
scale_y_continuous,
22+
theme,
23+
theme_minimal,
24+
)
25+
26+
27+
# Data - Simulate ROC curve from a good classifier
28+
np.random.seed(42)
29+
30+
# Generate realistic ROC curve data using beta distribution for smooth curve
31+
n_points = 200
32+
thresholds = np.linspace(0, 1, n_points)
33+
34+
# Model 1: Good classifier (AUC ~ 0.92)
35+
fpr_1 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 2.5), [1]]))
36+
tpr_1 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 0.4), [1]]))
37+
38+
# Model 2: Moderate classifier (AUC ~ 0.78)
39+
fpr_2 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 1.8), [1]]))
40+
tpr_2 = np.sort(np.concatenate([[0], np.power(thresholds[1:-1], 0.7), [1]]))
41+
42+
# Calculate AUC using trapezoidal rule
43+
auc_1 = np.trapezoid(tpr_1, fpr_1)
44+
auc_2 = np.trapezoid(tpr_2, fpr_2)
45+
46+
# Create DataFrame for plotting
47+
df = pd.DataFrame(
48+
{
49+
"fpr": np.concatenate([fpr_1, fpr_2]),
50+
"tpr": np.concatenate([tpr_1, tpr_2]),
51+
"Model": [f"Random Forest (AUC = {auc_1:.2f})"] * len(fpr_1)
52+
+ [f"Logistic Regression (AUC = {auc_2:.2f})"] * len(fpr_2),
53+
}
54+
)
55+
56+
# Create plot
57+
plot = (
58+
ggplot(df, aes(x="fpr", y="tpr", color="Model"))
59+
+ geom_abline(intercept=0, slope=1, linetype="dashed", color="#888888", size=1)
60+
+ geom_line(size=2.5, alpha=0.9)
61+
+ scale_color_manual(values=["#306998", "#FFD43B"])
62+
+ scale_x_continuous(limits=(0, 1), breaks=np.arange(0, 1.1, 0.2))
63+
+ scale_y_continuous(limits=(0, 1), breaks=np.arange(0, 1.1, 0.2))
64+
+ coord_fixed(ratio=1)
65+
+ labs(x="False Positive Rate", y="True Positive Rate", title="roc-curve · plotnine · pyplots.ai", color="Model")
66+
+ theme_minimal()
67+
+ theme(
68+
figure_size=(12, 12),
69+
text=element_text(size=14),
70+
axis_title=element_text(size=22, face="bold"),
71+
axis_text=element_text(size=18),
72+
plot_title=element_text(size=26, face="bold"),
73+
legend_text=element_text(size=18),
74+
legend_title=element_text(size=20, face="bold"),
75+
legend_position=(0.65, 0.25),
76+
legend_background=element_line(color="#CCCCCC", size=0.5),
77+
panel_grid_major=element_line(color="#DDDDDD", size=0.5, alpha=0.3),
78+
panel_grid_minor=element_line(color="#EEEEEE", size=0.3, alpha=0.2),
79+
)
80+
+ annotate("text", x=0.6, y=0.1, label="Diagonal = Random Classifier", size=12, color="#888888", fontstyle="italic")
81+
)
82+
83+
# Save plot
84+
plot.save("plot.png", dpi=300, width=12, height=12)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
library: plotnine
2+
specification_id: roc-curve
3+
created: '2025-12-26T17:38:09Z'
4+
updated: '2025-12-26T17:46:36Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20526595151
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 0.15.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/roc-curve/plotnine/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/roc-curve/plotnine/plot_thumb.png
12+
preview_html: null
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent visual clarity with well-sized text elements and line thickness
17+
- Clean implementation using plotnine grammar of graphics idiomatically
18+
- Proper use of coord_fixed(ratio=1) for equal aspect ratio as recommended for ROC
19+
curves
20+
- Good colorblind-accessible color choices (blue/yellow)
21+
- AUC values displayed in legend as required by spec
22+
- Professional annotation for diagonal reference line
23+
weaknesses:
24+
- Legend placement in lower-right creates slight visual imbalance; consider positioning
25+
at (0.7, 0.3)
26+
- Minor discrepancy between computed AUC values and displayed values

0 commit comments

Comments
 (0)