Skip to content

Commit 1273bc4

Browse files
feat(plotly): implement subplot-grid-custom (#2881)
## Implementation: `subplot-grid-custom` - plotly Implements the **plotly** version of `subplot-grid-custom`. **File:** `plots/subplot-grid-custom/implementations/plotly.py` **Parent Issue:** #2856 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20608469691)* --------- 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 bc4a548 commit 1273bc4

2 files changed

Lines changed: 152 additions & 0 deletions

File tree

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
""" pyplots.ai
2+
subplot-grid-custom: Custom Subplot Grid Layout
3+
Library: plotly 6.5.0 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-30
5+
"""
6+
7+
import numpy as np
8+
import pandas as pd
9+
import plotly.graph_objects as go
10+
from plotly.subplots import make_subplots
11+
12+
13+
# Data
14+
np.random.seed(42)
15+
16+
# Time series data for main plot (spanning 2 columns)
17+
dates = pd.date_range("2024-01-01", periods=120, freq="D")
18+
price = 100 + np.cumsum(np.random.randn(120) * 2)
19+
volume = np.random.randint(50, 200, 120)
20+
21+
# Returns data for histogram
22+
returns = np.diff(price) / price[:-1] * 100
23+
24+
# Scatter data for correlation plot
25+
revenue = np.random.uniform(50, 150, 50)
26+
expenses = revenue * 0.6 + np.random.randn(50) * 15
27+
28+
# Category data for bar chart
29+
categories = ["Product A", "Product B", "Product C", "Product D"]
30+
values = [85, 72, 91, 68]
31+
32+
# Create subplot grid: 2 rows × 3 columns
33+
# Main plot spans 2 columns in top row, small plots in remaining cells
34+
fig = make_subplots(
35+
rows=2,
36+
cols=3,
37+
specs=[[{"colspan": 2}, None, {}], [{}, {}, {}]],
38+
subplot_titles=(
39+
"Stock Price (2 Columns)",
40+
"Category Performance",
41+
"Trading Volume",
42+
"Revenue vs Expenses",
43+
"Daily Returns Distribution",
44+
),
45+
horizontal_spacing=0.08,
46+
vertical_spacing=0.15,
47+
)
48+
49+
# Main plot: Stock price time series (top-left, spans 2 columns)
50+
fig.add_trace(
51+
go.Scatter(
52+
x=dates, y=price, mode="lines", line={"color": "#306998", "width": 3}, name="Stock Price", showlegend=False
53+
),
54+
row=1,
55+
col=1,
56+
)
57+
58+
# Top-right: Category bar chart
59+
fig.add_trace(
60+
go.Bar(x=categories, y=values, marker_color="#FFD43B", name="Performance", showlegend=False), row=1, col=3
61+
)
62+
63+
# Bottom-left: Volume bar chart
64+
fig.add_trace(
65+
go.Bar(x=dates[::4], y=volume[::4], marker_color="#306998", opacity=0.7, name="Volume", showlegend=False),
66+
row=2,
67+
col=1,
68+
)
69+
70+
# Bottom-center: Scatter plot (revenue vs expenses)
71+
fig.add_trace(
72+
go.Scatter(
73+
x=revenue,
74+
y=expenses,
75+
mode="markers",
76+
marker={"color": "#306998", "size": 12, "opacity": 0.7, "line": {"color": "white", "width": 1}},
77+
name="Revenue vs Expenses",
78+
showlegend=False,
79+
),
80+
row=2,
81+
col=2,
82+
)
83+
84+
# Bottom-right: Returns histogram
85+
fig.add_trace(
86+
go.Histogram(x=returns, nbinsx=20, marker_color="#FFD43B", opacity=0.8, name="Returns", showlegend=False),
87+
row=2,
88+
col=3,
89+
)
90+
91+
# Update layout
92+
fig.update_layout(
93+
title={"text": "subplot-grid-custom · plotly · pyplots.ai", "font": {"size": 32}, "x": 0.5, "xanchor": "center"},
94+
template="plotly_white",
95+
showlegend=False,
96+
margin={"l": 80, "r": 60, "t": 120, "b": 80},
97+
)
98+
99+
# Update all axes with proper font sizes
100+
fig.update_xaxes(tickfont={"size": 14}, title_font={"size": 18})
101+
fig.update_yaxes(tickfont={"size": 14}, title_font={"size": 18})
102+
103+
# Update specific axes labels
104+
fig.update_xaxes(title_text="Date", row=1, col=1)
105+
fig.update_yaxes(title_text="Price ($)", row=1, col=1)
106+
107+
fig.update_xaxes(title_text="Category", row=1, col=3)
108+
fig.update_yaxes(title_text="Score", row=1, col=3)
109+
110+
fig.update_xaxes(title_text="Date", row=2, col=1)
111+
fig.update_yaxes(title_text="Volume (K)", row=2, col=1)
112+
113+
fig.update_xaxes(title_text="Revenue ($K)", row=2, col=2)
114+
fig.update_yaxes(title_text="Expenses ($K)", row=2, col=2)
115+
116+
fig.update_xaxes(title_text="Daily Return (%)", row=2, col=3)
117+
fig.update_yaxes(title_text="Frequency", row=2, col=3)
118+
119+
# Update annotation font sizes for subplot titles
120+
for annotation in fig["layout"]["annotations"]:
121+
annotation["font"] = {"size": 20}
122+
123+
# Save as PNG
124+
fig.write_image("plot.png", width=1600, height=900, scale=3)
125+
126+
# Save as HTML (interactive)
127+
fig.write_html("plot.html", include_plotlyjs=True, full_html=True)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library: plotly
2+
specification_id: subplot-grid-custom
3+
created: '2025-12-30T23:54:54Z'
4+
updated: '2025-12-31T00:01:09Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20608469691
7+
issue: 2856
8+
python_version: 3.13.11
9+
library_version: 6.5.0
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/subplot-grid-custom/plotly/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/subplot-grid-custom/plotly/plot_thumb.png
12+
preview_html: https://storage.googleapis.com/pyplots-images/plots/subplot-grid-custom/plotly/plot.html
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent implementation of custom subplot grid with colspan specification
17+
- Clean, well-structured code following KISS principles
18+
- Realistic financial dashboard scenario with coherent data story
19+
- Proper title format and good use of Python blue/yellow color scheme
20+
- All subplots have clear, descriptive titles and axis labels with units
21+
- Good use of plotly make_subplots with specs parameter for non-uniform grid
22+
weaknesses:
23+
- No rowspan demonstration (spec mentions both colspan AND rowspan)
24+
- Grid lines not visible (could add subtle grid for better readability)
25+
- Scatter plot markers could be slightly larger for the data density (50 points)

0 commit comments

Comments
 (0)