Skip to content

Commit d40f18f

Browse files
feat(seaborn): implement residual-plot (#2365)
## Implementation: `residual-plot` - seaborn Implements the **seaborn** version of `residual-plot`. **File:** `plots/residual-plot/implementations/seaborn.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20528203156)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 4.5 <noreply@anthropic.com> Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
1 parent 0958d8d commit d40f18f

2 files changed

Lines changed: 109 additions & 0 deletions

File tree

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
""" pyplots.ai
2+
residual-plot: Residual Plot
3+
Library: seaborn 0.13.2 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-26
5+
"""
6+
7+
import matplotlib.pyplot as plt
8+
import numpy as np
9+
import pandas as pd
10+
import seaborn as sns
11+
12+
13+
# Data - housing price prediction example
14+
np.random.seed(42)
15+
n_samples = 150
16+
17+
# Features: house size (sq ft)
18+
house_size = np.random.uniform(800, 3500, n_samples)
19+
20+
# True relationship with some non-linearity to show in residuals
21+
y_true = 50000 + 100 * house_size + 0.02 * house_size**2 + np.random.normal(0, 25000, n_samples)
22+
23+
# Fit linear model using numpy (will show pattern in residuals due to non-linearity)
24+
slope, intercept = np.polyfit(house_size, y_true, 1)
25+
y_pred = slope * house_size + intercept
26+
27+
# Calculate residuals
28+
residuals = y_true - y_pred
29+
30+
# Identify outliers (beyond 2 standard deviations)
31+
residual_std = np.std(residuals)
32+
outlier_mask = np.abs(residuals) > 2 * residual_std
33+
34+
# Create DataFrame for seaborn
35+
df = pd.DataFrame(
36+
{"Fitted Values": y_pred, "Residuals": residuals, "Type": np.where(outlier_mask, "Outlier (|z| > 2)", "Normal")}
37+
)
38+
39+
# Create plot
40+
fig, ax = plt.subplots(figsize=(16, 9))
41+
42+
# Plot using seaborn scatterplot with hue for outliers
43+
sns.scatterplot(
44+
data=df,
45+
x="Fitted Values",
46+
y="Residuals",
47+
hue="Type",
48+
palette={"Normal": "#306998", "Outlier (|z| > 2)": "#FFD43B"},
49+
s=150,
50+
alpha=0.7,
51+
ax=ax,
52+
)
53+
54+
# Add polynomial trend line using seaborn's regplot (order=2 for pattern detection)
55+
sns.regplot(
56+
data=df,
57+
x="Fitted Values",
58+
y="Residuals",
59+
scatter=False,
60+
order=2,
61+
line_kws={"color": "#C44536", "linewidth": 3, "alpha": 0.8, "label": "Trend"},
62+
ax=ax,
63+
)
64+
65+
# Reference line at y=0
66+
ax.axhline(y=0, color="#333333", linestyle="-", linewidth=2, zorder=1)
67+
68+
# Add ±2 standard deviation bands
69+
ax.axhline(y=2 * residual_std, color="#999999", linestyle="--", linewidth=1.5, alpha=0.7, label="±2 SD")
70+
ax.axhline(y=-2 * residual_std, color="#999999", linestyle="--", linewidth=1.5, alpha=0.7)
71+
72+
# Styling
73+
ax.set_xlabel("Fitted Values (Predicted Price in $)", fontsize=20)
74+
ax.set_ylabel("Residuals (Actual - Predicted)", fontsize=20)
75+
ax.set_title("residual-plot · seaborn · pyplots.ai", fontsize=24)
76+
ax.tick_params(axis="both", labelsize=16)
77+
ax.legend(fontsize=14, loc="upper right", framealpha=0.9)
78+
ax.grid(True, alpha=0.3, linestyle="--")
79+
80+
plt.tight_layout()
81+
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
library: seaborn
2+
specification_id: residual-plot
3+
created: '2025-12-26T19:38:17Z'
4+
updated: '2025-12-26T19:44:37Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20528203156
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/residual-plot/seaborn/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/residual-plot/seaborn/plot_thumb.png
12+
preview_html: null
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent use of housing price prediction as a realistic regression context that
17+
makes the residual analysis meaningful
18+
- Clear U-shaped trend in residuals demonstrates non-linearity detection, which
19+
is the primary purpose of residual plots
20+
- Good implementation of outlier highlighting with color differentiation (blue/yellow)
21+
using hue parameter
22+
- Reference line at y=0 and ±2 SD bands provide clear visual guides for interpretation
23+
- Proper use of seaborn regplot for polynomial trend line with confidence interval
24+
weaknesses:
25+
- Does not use seaborn built-in residplot function which is specifically designed
26+
for this plot type
27+
- The Trend label in regplot line_kws does not appear in the legend (seaborn regplot
28+
does not add to legend automatically)

0 commit comments

Comments
 (0)