Skip to content

Commit 57c5f2c

Browse files
feat(plotnine): implement line-timeseries-rolling (#2840)
## Implementation: `line-timeseries-rolling` - plotnine Implements the **plotnine** version of `line-timeseries-rolling`. **File:** `plots/line-timeseries-rolling/implementations/plotnine.py` --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/pyplots/actions/runs/20603334572)* --------- 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 3917615 commit 57c5f2c

2 files changed

Lines changed: 113 additions & 0 deletions

File tree

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
""" pyplots.ai
2+
line-timeseries-rolling: Time Series with Rolling Average Overlay
3+
Library: plotnine 0.15.2 | 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+
from mizani.breaks import breaks_date
10+
from mizani.labels import label_date
11+
from plotnine import (
12+
aes,
13+
element_line,
14+
element_text,
15+
geom_line,
16+
ggplot,
17+
guides,
18+
labs,
19+
scale_alpha_manual,
20+
scale_color_manual,
21+
scale_size_manual,
22+
scale_x_datetime,
23+
theme,
24+
theme_minimal,
25+
)
26+
27+
28+
# Data - Daily temperature readings with 7-day rolling average
29+
np.random.seed(42)
30+
31+
# Generate 180 days of temperature data (6 months)
32+
dates = pd.date_range("2024-01-01", periods=180, freq="D")
33+
34+
# Create seasonal temperature pattern with noise
35+
# Base seasonal pattern: winter -> spring -> summer
36+
day_of_year = np.arange(180)
37+
seasonal = 5 + 15 * np.sin(2 * np.pi * (day_of_year - 30) / 365)
38+
noise = np.random.normal(0, 3, 180)
39+
temperature = seasonal + noise
40+
41+
# Create DataFrame and calculate rolling average
42+
df = pd.DataFrame({"date": dates, "temperature": temperature})
43+
df["rolling_avg"] = df["temperature"].rolling(window=7, center=True).mean()
44+
45+
# Reshape data for plotnine - need long format for multiple series
46+
df_raw = df[["date", "temperature"]].copy()
47+
df_raw["series"] = "Daily Temperature"
48+
df_raw = df_raw.rename(columns={"temperature": "value"})
49+
50+
df_roll = df[["date", "rolling_avg"]].dropna().copy()
51+
df_roll["series"] = "7-Day Rolling Average"
52+
df_roll = df_roll.rename(columns={"rolling_avg": "value"})
53+
54+
df_long = pd.concat([df_raw, df_roll], ignore_index=True)
55+
56+
# Make series categorical for consistent ordering
57+
df_long["series"] = pd.Categorical(
58+
df_long["series"], categories=["Daily Temperature", "7-Day Rolling Average"], ordered=True
59+
)
60+
61+
# Plot
62+
plot = (
63+
ggplot(df_long, aes(x="date", y="value", color="series", alpha="series", size="series"))
64+
+ geom_line()
65+
+ scale_color_manual(values={"Daily Temperature": "#306998", "7-Day Rolling Average": "#FFD43B"})
66+
+ scale_alpha_manual(values={"Daily Temperature": 0.5, "7-Day Rolling Average": 1.0})
67+
+ scale_size_manual(values={"Daily Temperature": 0.8, "7-Day Rolling Average": 2.0})
68+
+ guides(alpha="none", size="none")
69+
+ scale_x_datetime(breaks=breaks_date(7), labels=label_date("%b %Y"))
70+
+ labs(x="Date", y="Temperature (°C)", title="line-timeseries-rolling · plotnine · pyplots.ai", color="")
71+
+ theme_minimal()
72+
+ theme(
73+
figure_size=(16, 9),
74+
text=element_text(size=14),
75+
plot_title=element_text(size=24),
76+
axis_title=element_text(size=20),
77+
axis_text=element_text(size=16),
78+
axis_text_x=element_text(angle=30, hjust=1),
79+
legend_text=element_text(size=16),
80+
legend_title=element_text(size=0),
81+
legend_position="right",
82+
panel_grid_major=element_line(color="#cccccc", size=0.5, alpha=0.3),
83+
panel_grid_minor=element_line(color="#dddddd", size=0.3, alpha=0.2),
84+
)
85+
)
86+
87+
# Save
88+
plot.save("plot.png", dpi=300, verbose=False)
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
library: plotnine
2+
specification_id: line-timeseries-rolling
3+
created: '2025-12-30T18:40:03Z'
4+
updated: '2025-12-30T18:42:10Z'
5+
generated_by: claude-opus-4-5-20251101
6+
workflow_run: 20603334572
7+
issue: 0
8+
python_version: 3.13.11
9+
library_version: 0.15.2
10+
preview_url: https://storage.googleapis.com/pyplots-images/plots/line-timeseries-rolling/plotnine/plot.png
11+
preview_thumb: https://storage.googleapis.com/pyplots-images/plots/line-timeseries-rolling/plotnine/plot_thumb.png
12+
preview_html: null
13+
quality_score: 92
14+
review:
15+
strengths:
16+
- Excellent use of plotnine grammar of graphics with proper aesthetics mapping for
17+
color, alpha, and size
18+
- Clear visual distinction between raw data (lighter blue, thin line) and rolling
19+
average (prominent yellow, thicker line)
20+
- Proper title format following pyplots.ai conventions
21+
- Good use of scale_alpha_manual and scale_size_manual for visual differentiation
22+
- Well-structured data transformation to long format for ggplot-style plotting
23+
weaknesses:
24+
- X-axis date labels are slightly crowded with 7-day breaks over 6 months - could
25+
use monthly breaks for cleaner appearance

0 commit comments

Comments
 (0)