Skip to content

Commit 7b9a362

Browse files
feat(seaborn): implement line-annotated-events (#3011)
## Implementation: `line-annotated-events` - seaborn Implements the **seaborn** version of `line-annotated-events`. **File:** `plots/line-annotated-events/implementations/seaborn.py` **Parent Issue:** #2997 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20617488740)* --------- 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 1cc95dc commit 7b9a362

2 files changed

Lines changed: 111 additions & 0 deletions

File tree

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
""" pyplots.ai
2+
line-annotated-events: Annotated Line Plot with Event Markers
3+
Library: seaborn 0.13.2 | Python 3.13.11
4+
Quality: 92/100 | Created: 2025-12-31
5+
"""
6+
7+
import matplotlib.pyplot as plt
8+
import numpy as np
9+
import pandas as pd
10+
import seaborn as sns
11+
12+
13+
# Data - Simulating monthly product sales with marketing events
14+
np.random.seed(42)
15+
16+
# Create 12 months of sales data
17+
dates = pd.date_range("2024-01-01", periods=365, freq="D")
18+
# Base trend with seasonality and noise
19+
trend = np.linspace(100, 180, 365)
20+
seasonality = 15 * np.sin(np.linspace(0, 4 * np.pi, 365))
21+
noise = np.random.normal(0, 8, 365)
22+
sales = trend + seasonality + noise
23+
24+
df = pd.DataFrame({"date": dates, "sales": sales})
25+
26+
# Events - Key marketing milestones
27+
events = pd.DataFrame(
28+
{
29+
"event_date": pd.to_datetime(["2024-02-14", "2024-05-01", "2024-07-15", "2024-09-20", "2024-11-25"]),
30+
"event_label": ["Valentine's Campaign", "Spring Sale", "Summer Launch", "Fall Promotion", "Black Friday"],
31+
}
32+
)
33+
34+
# Plot
35+
fig, ax = plt.subplots(figsize=(16, 9))
36+
37+
# Main line plot using seaborn
38+
sns.lineplot(data=df, x="date", y="sales", ax=ax, linewidth=2.5, color="#306998")
39+
40+
# Add event markers with alternating heights for readability
41+
y_positions = [0.85, 0.75, 0.85, 0.75, 0.85] # Alternating label positions
42+
colors_events = ["#FFD43B"] * len(events) # Use Python Yellow for all events
43+
44+
for i, (_, event) in enumerate(events.iterrows()):
45+
# Vertical line at event date
46+
ax.axvline(x=event["event_date"], color=colors_events[i], linestyle="--", linewidth=2, alpha=0.8)
47+
48+
# Event label with background
49+
y_pos = ax.get_ylim()[0] + (ax.get_ylim()[1] - ax.get_ylim()[0]) * y_positions[i]
50+
ax.annotate(
51+
event["event_label"],
52+
xy=(event["event_date"], y_pos),
53+
fontsize=14,
54+
fontweight="bold",
55+
color="#333333",
56+
ha="center",
57+
va="bottom",
58+
bbox={"boxstyle": "round,pad=0.3", "facecolor": "#FFD43B", "edgecolor": "none", "alpha": 0.9},
59+
rotation=0,
60+
)
61+
62+
# Small marker on the line at event date
63+
event_sales = df.loc[df["date"] == event["event_date"], "sales"]
64+
if not event_sales.empty:
65+
ax.scatter(
66+
event["event_date"],
67+
event_sales.values[0],
68+
color="#FFD43B",
69+
s=150,
70+
zorder=5,
71+
edgecolor="#333333",
72+
linewidth=2,
73+
)
74+
75+
# Styling
76+
ax.set_xlabel("Date", fontsize=20)
77+
ax.set_ylabel("Daily Sales (Units)", fontsize=20)
78+
ax.set_title("line-annotated-events · seaborn · pyplots.ai", fontsize=24)
79+
ax.tick_params(axis="both", labelsize=16)
80+
ax.grid(True, alpha=0.3, linestyle="--")
81+
82+
# Format x-axis dates
83+
fig.autofmt_xdate(rotation=30)
84+
85+
plt.tight_layout()
86+
plt.savefig("plot.png", dpi=300, bbox_inches="tight")
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library: seaborn
2+
specification_id: line-annotated-events
3+
created: '2025-12-31T10:54:41Z'
4+
updated: '2025-12-31T10:59:41Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20617488740
7+
issue: 2997
8+
python_version: 3.13.11
9+
library_version: 0.13.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/line-annotated-events/seaborn/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/line-annotated-events/seaborn/plot_thumb.png
12+
preview_html: null
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent use of alternating label heights to prevent overlap with dense events
17+
- 'Clear visual hierarchy: blue data line, yellow event markers create strong contrast'
18+
- Comprehensive data generation with realistic trend, seasonality, and noise
19+
- Proper handling of event markers on the actual data line with scatter points
20+
- Well-sized text elements for readability at high resolution
21+
weaknesses:
22+
- No legend or key explaining the event marker style (spec mentions including a
23+
subtle legend or key)
24+
- Realistic context score could be higher with more domain-specific context (e.g.,
25+
actual product category mentioned in labels)

0 commit comments

Comments
 (0)