Skip to content

Commit cd224e1

Browse files
feat(matplotlib): implement subplot-grid (#2812)
## Implementation: `subplot-grid` - matplotlib Implements the **matplotlib** version of `subplot-grid`. **File:** `plots/subplot-grid/implementations/matplotlib.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20602446975)* --------- 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 bfdc335 commit cd224e1

2 files changed

Lines changed: 117 additions & 0 deletions

File tree

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
""" pyplots.ai
2+
subplot-grid: Subplot Grid Layout
3+
Library: matplotlib 3.10.8 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-30
5+
"""
6+
7+
import matplotlib.pyplot as plt
8+
import numpy as np
9+
10+
11+
# Data - Financial dashboard example
12+
np.random.seed(42)
13+
14+
# Time axis (trading days)
15+
days = np.arange(1, 101)
16+
17+
# Price data (random walk with drift)
18+
price_changes = np.random.randn(100) * 2 + 0.05
19+
prices = 100 + np.cumsum(price_changes)
20+
21+
# Volume data (lognormal distribution)
22+
volumes = np.random.lognormal(mean=10, sigma=0.5, size=100)
23+
24+
# Daily returns
25+
returns = np.diff(prices) / prices[:-1] * 100
26+
27+
# Moving averages
28+
ma_20 = np.convolve(prices, np.ones(20) / 20, mode="valid")
29+
30+
# Create 2x2 subplot grid
31+
fig, axes = plt.subplots(2, 2, figsize=(16, 9))
32+
33+
# Subplot 1: Price Line Chart (top-left)
34+
ax1 = axes[0, 0]
35+
ax1.plot(days, prices, linewidth=2.5, color="#306998", label="Price")
36+
ax1.plot(days[19:], ma_20, linewidth=2, color="#FFD43B", linestyle="--", label="20-day MA")
37+
ax1.set_xlabel("Trading Day", fontsize=16)
38+
ax1.set_ylabel("Price ($)", fontsize=16)
39+
ax1.set_title("Stock Price", fontsize=18, fontweight="bold")
40+
ax1.tick_params(axis="both", labelsize=14)
41+
ax1.legend(fontsize=14, loc="upper left")
42+
ax1.grid(True, alpha=0.3, linestyle="--")
43+
44+
# Subplot 2: Volume Bar Chart (top-right)
45+
ax2 = axes[0, 1]
46+
colors = ["#306998" if r >= 0 else "#D94A4A" for r in np.append(0, returns)]
47+
ax2.bar(days, volumes / 1000, width=0.8, color=colors, alpha=0.8, edgecolor="none")
48+
ax2.set_xlabel("Trading Day", fontsize=16)
49+
ax2.set_ylabel("Volume (thousands)", fontsize=16)
50+
ax2.set_title("Trading Volume", fontsize=18, fontweight="bold")
51+
ax2.tick_params(axis="both", labelsize=14)
52+
ax2.grid(True, alpha=0.3, linestyle="--", axis="y")
53+
54+
# Subplot 3: Returns Histogram (bottom-left)
55+
ax3 = axes[1, 0]
56+
ax3.hist(returns, bins=20, color="#306998", edgecolor="white", linewidth=1.5, alpha=0.8)
57+
ax3.axvline(x=0, color="#FFD43B", linewidth=2.5, linestyle="-", label="Zero Return")
58+
ax3.axvline(x=np.mean(returns), color="#D94A4A", linewidth=2.5, linestyle="--", label=f"Mean: {np.mean(returns):.2f}%")
59+
ax3.set_xlabel("Daily Return (%)", fontsize=16)
60+
ax3.set_ylabel("Frequency", fontsize=16)
61+
ax3.set_title("Return Distribution", fontsize=18, fontweight="bold")
62+
ax3.tick_params(axis="both", labelsize=14)
63+
ax3.legend(fontsize=12, loc="upper right")
64+
ax3.grid(True, alpha=0.3, linestyle="--", axis="y")
65+
66+
# Subplot 4: Price vs Volume Scatter (bottom-right)
67+
ax4 = axes[1, 1]
68+
scatter = ax4.scatter(
69+
volumes[1:] / 1000, # Match returns size (99 elements)
70+
np.abs(returns),
71+
s=80,
72+
c=returns,
73+
cmap="RdYlGn",
74+
alpha=0.7,
75+
edgecolor="white",
76+
linewidth=0.5,
77+
)
78+
ax4.set_xlabel("Volume (thousands)", fontsize=16)
79+
ax4.set_ylabel("Absolute Return (%)", fontsize=16)
80+
ax4.set_title("Volume vs Return Magnitude", fontsize=18, fontweight="bold")
81+
ax4.tick_params(axis="both", labelsize=14)
82+
cbar = plt.colorbar(scatter, ax=ax4)
83+
cbar.ax.tick_params(labelsize=12)
84+
cbar.set_label("Return (%)", fontsize=14)
85+
ax4.grid(True, alpha=0.3, linestyle="--")
86+
87+
# Main title
88+
fig.suptitle("subplot-grid · matplotlib · pyplots.ai", fontsize=24, fontweight="bold", y=0.98)
89+
90+
plt.tight_layout(rect=[0, 0, 1, 0.95])
91+
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: matplotlib
2+
specification_id: subplot-grid
3+
created: '2025-12-30T17:48:50Z'
4+
updated: '2025-12-30T17:56:40Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20602446975
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 3.10.8
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/subplot-grid/matplotlib/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/subplot-grid/matplotlib/plot_thumb.png
12+
preview_html: null
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent financial dashboard example perfectly demonstrating the subplot-grid
17+
concept with four distinct but related visualizations
18+
- 'Creative color encoding: volume bars colored by return sign, scatter colored
19+
by return value'
20+
- Moving average overlay adds depth to the price chart
21+
- Statistical annotations (mean, zero line) in histogram enhance educational value
22+
- Clean, professional appearance with consistent styling across all subplots
23+
weaknesses:
24+
- Font sizes slightly below recommended guidelines (titles 18pt vs 24pt, labels
25+
16pt vs 20pt)
26+
- Legend fontsize could be larger for better readability (12-14 vs 16)

0 commit comments

Comments
 (0)