Skip to content

Commit 9e9fd06

Browse files
feat(matplotlib): implement line-annotated-events (#3020)
## Implementation: `line-annotated-events` - matplotlib Implements the **matplotlib** version of `line-annotated-events`. **File:** `plots/line-annotated-events/implementations/matplotlib.py` **Parent Issue:** #2997 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20617489492)* --------- 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 295ab2a commit 9e9fd06

2 files changed

Lines changed: 97 additions & 0 deletions

File tree

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
""" pyplots.ai
2+
line-annotated-events: Annotated Line Plot with Event Markers
3+
Library: matplotlib 3.10.8 | Python 3.13.11
4+
Quality: 91/100 | Created: 2025-12-31
5+
"""
6+
7+
import matplotlib.pyplot as plt
8+
import numpy as np
9+
import pandas as pd
10+
11+
12+
# Data
13+
np.random.seed(42)
14+
dates = pd.date_range("2024-01-01", periods=365, freq="D")
15+
# Generate realistic stock-like price data with trend and volatility
16+
base_price = 150
17+
returns = np.random.randn(365) * 0.015 # Daily returns ~1.5% std
18+
prices = base_price * np.cumprod(1 + returns)
19+
20+
# Event dates and labels (quarterly earnings + major announcements)
21+
events = [
22+
(pd.Timestamp("2024-02-15"), "Q4 2023\nEarnings"),
23+
(pd.Timestamp("2024-05-10"), "Q1 2024\nEarnings"),
24+
(pd.Timestamp("2024-07-22"), "Product\nLaunch"),
25+
(pd.Timestamp("2024-08-08"), "Q2 2024\nEarnings"),
26+
(pd.Timestamp("2024-11-14"), "Q3 2024\nEarnings"),
27+
]
28+
29+
# Plot
30+
fig, ax = plt.subplots(figsize=(16, 9))
31+
32+
# Main line
33+
ax.plot(dates, prices, linewidth=2.5, color="#306998", label="Stock Price", zorder=2)
34+
35+
# Event markers with alternating heights
36+
event_colors = "#FFD43B"
37+
heights = [0.85, 0.70, 0.85, 0.70, 0.85] # Alternating heights to avoid overlap
38+
39+
for i, (event_date, event_label) in enumerate(events):
40+
# Vertical line
41+
ax.axvline(x=event_date, color=event_colors, linestyle="--", linewidth=2, alpha=0.8, zorder=1)
42+
# Text annotation with alternating heights
43+
y_pos = ax.get_ylim()[0] + (ax.get_ylim()[1] - ax.get_ylim()[0]) * heights[i]
44+
ax.annotate(
45+
event_label,
46+
xy=(event_date, prices[dates.get_loc(event_date)]),
47+
xytext=(event_date, y_pos),
48+
fontsize=14,
49+
ha="center",
50+
va="bottom",
51+
color="#333333",
52+
bbox={"boxstyle": "round,pad=0.3", "facecolor": "white", "edgecolor": "#FFD43B", "alpha": 0.9},
53+
arrowprops={"arrowstyle": "->", "color": "#FFD43B", "lw": 1.5},
54+
)
55+
56+
# Add event marker to legend
57+
ax.axvline(x=dates[0], color=event_colors, linestyle="--", linewidth=2, alpha=0, label="Event Marker")
58+
59+
# Styling
60+
ax.set_xlabel("Date", fontsize=20)
61+
ax.set_ylabel("Price (USD)", fontsize=20)
62+
ax.set_title("line-annotated-events · matplotlib · pyplots.ai", fontsize=24)
63+
ax.tick_params(axis="both", labelsize=16)
64+
ax.grid(True, alpha=0.3, linestyle="--")
65+
ax.legend(fontsize=16, loc="upper left")
66+
67+
# Format x-axis for better date readability
68+
fig.autofmt_xdate(rotation=30)
69+
70+
plt.tight_layout()
71+
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: line-annotated-events
3+
created: '2025-12-31T10:55:32Z'
4+
updated: '2025-12-31T11:04:51Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20617489492
7+
issue: 2997
8+
python_version: 3.13.11
9+
library_version: 3.10.8
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/line-annotated-events/matplotlib/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/line-annotated-events/matplotlib/plot_thumb.png
12+
preview_html: null
13+
quality_score: 91
14+
review:
15+
strengths:
16+
- Excellent implementation of the spec with clear event annotations using axvline
17+
and annotate
18+
- Smart use of alternating heights to prevent annotation overlap
19+
- Professional styling with white background boxes and arrow connections
20+
- Realistic stock price data with quarterly earnings context
21+
- Clean KISS code structure with proper seed for reproducibility
22+
weaknesses:
23+
- Legend entry for Event Marker uses alpha=0 trick which creates an invisible line
24+
in the legend - consider using a Line2D proxy artist instead
25+
- Could utilize more distinctive matplotlib features like ConnectionPatch for arrows
26+
or custom box styles

0 commit comments

Comments
 (0)