Skip to content

Commit 03fb48d

Browse files
feat(seaborn): implement subplot-grid-custom (#2875)
## Implementation: `subplot-grid-custom` - seaborn Implements the **seaborn** version of `subplot-grid-custom`. **File:** `plots/subplot-grid-custom/implementations/seaborn.py` **Parent Issue:** #2856 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20608469916)* --------- 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 2ab64f8 commit 03fb48d

2 files changed

Lines changed: 152 additions & 0 deletions

File tree

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
""" pyplots.ai
2+
subplot-grid-custom: Custom Subplot Grid Layout
3+
Library: seaborn 0.13.2 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-30
5+
"""
6+
7+
import matplotlib.dates as mdates
8+
import matplotlib.gridspec as gridspec
9+
import matplotlib.pyplot as plt
10+
import numpy as np
11+
import pandas as pd
12+
import seaborn as sns
13+
14+
15+
# Data
16+
np.random.seed(42)
17+
18+
# Time series data for main plot (spanning 2 columns)
19+
dates = pd.date_range("2024-01-01", periods=120, freq="D")
20+
price = 100 + np.cumsum(np.random.randn(120) * 2)
21+
df_main = pd.DataFrame({"Date": dates, "Price": price})
22+
23+
# Volume bar data
24+
volume = np.random.randint(1000, 5000, size=12)
25+
months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
26+
df_volume = pd.DataFrame({"Month": months, "Volume": volume})
27+
28+
# Returns histogram data
29+
returns = np.diff(price) / price[:-1] * 100
30+
df_returns = pd.DataFrame({"Returns": returns})
31+
32+
# Scatter plot data
33+
x_scatter = np.random.randn(80) * 15 + 50
34+
y_scatter = x_scatter * 0.8 + np.random.randn(80) * 10 + 20
35+
df_scatter = pd.DataFrame({"Variable_X": x_scatter, "Variable_Y": y_scatter})
36+
37+
# Category boxplot data
38+
categories = np.repeat(["Q1", "Q2", "Q3", "Q4"], 30)
39+
values = np.concatenate(
40+
[
41+
np.random.normal(50, 10, 30),
42+
np.random.normal(55, 12, 30),
43+
np.random.normal(60, 8, 30),
44+
np.random.normal(65, 15, 30),
45+
]
46+
)
47+
df_box = pd.DataFrame({"Quarter": categories, "Performance": values})
48+
49+
# Create figure with GridSpec layout
50+
fig = plt.figure(figsize=(16, 9))
51+
gs = gridspec.GridSpec(3, 3, figure=fig, hspace=0.45, wspace=0.30)
52+
53+
# Main plot: Time series spanning 2 columns (top-left 2x2 area)
54+
ax_main = fig.add_subplot(gs[0:2, 0:2])
55+
sns.lineplot(data=df_main, x="Date", y="Price", ax=ax_main, linewidth=3, color="#306998")
56+
ax_main.set_title("Daily Price Trend", fontsize=20, fontweight="bold")
57+
ax_main.set_xlabel("Date", fontsize=16)
58+
ax_main.set_ylabel("Price ($)", fontsize=16)
59+
ax_main.tick_params(axis="both", labelsize=12)
60+
ax_main.tick_params(axis="x", rotation=0)
61+
ax_main.grid(True, alpha=0.3, linestyle="--")
62+
ax_main.fill_between(df_main["Date"], df_main["Price"], alpha=0.2, color="#306998")
63+
ax_main.xaxis.set_major_locator(plt.MaxNLocator(5))
64+
ax_main.xaxis.set_major_formatter(mdates.DateFormatter("%b %d"))
65+
66+
# Top-right: Scatter plot
67+
ax_scatter = fig.add_subplot(gs[0, 2])
68+
sns.scatterplot(data=df_scatter, x="Variable_X", y="Variable_Y", ax=ax_scatter, s=120, alpha=0.7, color="#FFD43B")
69+
ax_scatter.set_title("Correlation Analysis", fontsize=16, fontweight="bold")
70+
ax_scatter.set_xlabel("Variable X", fontsize=14)
71+
ax_scatter.set_ylabel("Variable Y", fontsize=14)
72+
ax_scatter.tick_params(axis="both", labelsize=12)
73+
ax_scatter.grid(True, alpha=0.3, linestyle="--")
74+
75+
# Middle-right: Boxplot (spanning vertically)
76+
ax_box = fig.add_subplot(gs[1, 2])
77+
sns.boxplot(data=df_box, x="Quarter", y="Performance", hue="Quarter", ax=ax_box, palette="Set2", legend=False)
78+
ax_box.set_title("Quarterly Performance", fontsize=16, fontweight="bold")
79+
ax_box.set_xlabel("Quarter", fontsize=14)
80+
ax_box.set_ylabel("Performance Score", fontsize=14)
81+
ax_box.tick_params(axis="both", labelsize=12)
82+
83+
# Bottom-left: Volume bar chart
84+
ax_volume = fig.add_subplot(gs[2, 0])
85+
sns.barplot(data=df_volume, x="Month", y="Volume", hue="Month", ax=ax_volume, palette="viridis", legend=False)
86+
ax_volume.set_title("Monthly Volume", fontsize=16, fontweight="bold")
87+
ax_volume.set_xlabel("Month", fontsize=14)
88+
ax_volume.set_ylabel("Volume (Units)", fontsize=14)
89+
ax_volume.tick_params(axis="x", labelsize=10, rotation=45)
90+
ax_volume.tick_params(axis="y", labelsize=12)
91+
92+
# Bottom-center: Returns histogram
93+
ax_hist = fig.add_subplot(gs[2, 1])
94+
sns.histplot(data=df_returns, x="Returns", kde=True, ax=ax_hist, color="#306998", alpha=0.7, bins=20)
95+
ax_hist.set_title("Returns Distribution", fontsize=16, fontweight="bold")
96+
ax_hist.set_xlabel("Daily Returns (%)", fontsize=14)
97+
ax_hist.set_ylabel("Frequency", fontsize=14)
98+
ax_hist.tick_params(axis="both", labelsize=12)
99+
ax_hist.axvline(x=0, color="#FFD43B", linewidth=2, linestyle="--", alpha=0.8)
100+
101+
# Bottom-right: Summary heatmap (correlation-style)
102+
correlation_data = np.array([[1.0, 0.65, 0.42], [0.65, 1.0, 0.58], [0.42, 0.58, 1.0]])
103+
labels = ["Price", "Volume", "Returns"]
104+
ax_heatmap = fig.add_subplot(gs[2, 2])
105+
sns.heatmap(
106+
correlation_data,
107+
annot=True,
108+
fmt=".2f",
109+
xticklabels=labels,
110+
yticklabels=labels,
111+
ax=ax_heatmap,
112+
cmap="RdBu_r",
113+
center=0,
114+
vmin=-1,
115+
vmax=1,
116+
annot_kws={"size": 14},
117+
cbar_kws={"shrink": 0.8},
118+
)
119+
ax_heatmap.set_title("Correlation Matrix", fontsize=16, fontweight="bold")
120+
ax_heatmap.tick_params(axis="both", labelsize=12)
121+
122+
# Main title
123+
fig.suptitle("subplot-grid-custom · seaborn · pyplots.ai", fontsize=24, fontweight="bold", y=0.98)
124+
125+
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
library: seaborn
2+
specification_id: subplot-grid-custom
3+
created: '2025-12-30T23:54:20Z'
4+
updated: '2025-12-30T23:58:58Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20608469916
7+
issue: 2856
8+
python_version: 3.13.11
9+
library_version: 0.13.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/subplot-grid-custom/seaborn/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/subplot-grid-custom/seaborn/plot_thumb.png
12+
preview_html: null
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent dashboard layout demonstrating GridSpec with main plot spanning 2x2
17+
cells
18+
- Good variety of seaborn plot types (6 different visualizations) showcasing library
19+
breadth
20+
- Financial dashboard scenario is realistic and coherent with interconnected data
21+
(price, volume, returns, correlations)
22+
- Proper use of seaborn 0.14+ API with hue parameter for palettes
23+
- Clean color scheme with colorblind-safe palettes (viridis, Set2, RdBu_r)
24+
weaknesses:
25+
- Missing rowspan example - spec mentions cells spanning multiple rows (e.g., tall
26+
sidebar plot) but all cells only span columns
27+
- Heatmap y-axis label text appears concatenated/overlapping due to tight spacing

0 commit comments

Comments
 (0)