Skip to content

Commit 50dd5a3

Browse files
feat(matplotlib): implement span-basic (#5610)
## Implementation: `span-basic` - python/matplotlib Implements the **python/matplotlib** version of `span-basic`. **File:** `plots/span-basic/implementations/python/matplotlib.py` **Parent Issue:** #980 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/25160721973)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent b603e60 commit 50dd5a3

2 files changed

Lines changed: 210 additions & 158 deletions

File tree

Lines changed: 49 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,66 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
span-basic: Basic Span Plot (Highlighted Region)
3-
Library: matplotlib 3.10.8 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: matplotlib 3.10.9 | Python 3.13.13
4+
Quality: 91/100 | Updated: 2026-04-30
55
"""
66

7+
import os
8+
79
import matplotlib.pyplot as plt
810
import numpy as np
911

1012

11-
# Data - Stock prices with highlighted recession period
12-
np.random.seed(42)
13-
dates = np.arange(2006, 2016, 0.1) # 10 years of data
13+
# Theme tokens
14+
THEME = os.getenv("ANYPLOT_THEME", "light")
15+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
16+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
17+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
18+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
19+
INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F"
1420

15-
# Simulate stock price with trend and volatility
16-
price = 100 + np.cumsum(np.random.randn(len(dates)) * 2)
21+
BRAND = "#009E73" # Okabe-Ito position 1 — first series
22+
C2 = "#D55E00" # Okabe-Ito position 2
23+
C3 = "#0072B2" # Okabe-Ito position 3
24+
25+
# Data — stock prices with a simulated recession dip
26+
np.random.seed(42)
27+
dates = np.arange(2004, 2016, 0.1)
1728

18-
# Add a dip during recession period (2008-2009)
29+
price = 100 + np.cumsum(np.random.randn(len(dates)) * 1.5)
1930
recession_mask = (dates >= 2008) & (dates < 2010)
20-
price[recession_mask] -= np.linspace(0, 30, recession_mask.sum())
21-
price[dates >= 2010] -= 30
22-
price = price + np.abs(price.min()) + 50 # Keep positive
31+
price[recession_mask] -= np.linspace(0, 35, recession_mask.sum())
32+
price[dates >= 2010] -= 35
33+
price = price - price.min() + 70
34+
35+
# Plot
36+
fig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)
37+
ax.set_facecolor(PAGE_BG)
38+
39+
ax.plot(dates, price, linewidth=3, color=BRAND, label="Stock Price Index")
40+
41+
# Vertical span — recession period (2008–2009)
42+
ax.axvspan(2008, 2010, alpha=0.22, color=C2, label="Recession Period")
2343

24-
# Create plot (4800x2700 px)
25-
fig, ax = plt.subplots(figsize=(16, 9))
44+
# Horizontal span — risk zone (low values)
45+
ax.axhspan(70, 95, alpha=0.18, color=C3, label="Risk Zone")
2646

27-
# Plot line data
28-
ax.plot(dates, price, linewidth=3, color="#306998", label="Stock Price")
47+
# Style
48+
ax.set_xlabel("Year", fontsize=20, color=INK)
49+
ax.set_ylabel("Price Index", fontsize=20, color=INK)
50+
ax.set_title("span-basic · matplotlib · anyplot.ai", fontsize=24, fontweight="medium", color=INK)
51+
ax.tick_params(axis="both", labelsize=16, colors=INK_SOFT, labelcolor=INK_SOFT)
2952

30-
# Vertical span highlighting recession period (2008-2009)
31-
ax.axvspan(2008, 2009, alpha=0.25, color="#FFD43B", label="Recession Period")
53+
ax.spines["top"].set_visible(False)
54+
ax.spines["right"].set_visible(False)
55+
for spine in ("left", "bottom"):
56+
ax.spines[spine].set_color(INK_SOFT)
3257

33-
# Horizontal span highlighting danger zone (low values)
34-
ax.axhspan(60, 80, alpha=0.2, color="#D62728", label="Risk Zone")
58+
ax.yaxis.grid(True, alpha=0.12, linewidth=0.8, color=INK)
3559

36-
# Labels and styling
37-
ax.set_xlabel("Year", fontsize=20)
38-
ax.set_ylabel("Price ($)", fontsize=20)
39-
ax.set_title("span-basic · matplotlib · pyplots.ai", fontsize=24)
40-
ax.tick_params(axis="both", labelsize=16)
41-
ax.grid(True, alpha=0.3, linestyle="--")
42-
ax.legend(fontsize=16, loc="upper left")
60+
leg = ax.legend(fontsize=16, loc="upper left")
61+
leg.get_frame().set_facecolor(ELEVATED_BG)
62+
leg.get_frame().set_edgecolor(INK_SOFT)
63+
plt.setp(leg.get_texts(), color=INK_SOFT)
4364

4465
plt.tight_layout()
45-
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
66+
plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG)

0 commit comments

Comments
 (0)