Skip to content

Commit 9f3b78b

Browse files
feat(plotnine): implement line-timeseries (#6120)
## Implementation: `line-timeseries` - python/plotnine Implements the **python/plotnine** version of `line-timeseries`. **File:** `plots/line-timeseries/implementations/python/plotnine.py` **Parent Issue:** #2006 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/25590428403)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com> Co-authored-by: Markus Neusinger <2921697+MarkusNeusinger@users.noreply.github.com>
1 parent dc1b07a commit 9f3b78b

2 files changed

Lines changed: 174 additions & 141 deletions

File tree

Lines changed: 37 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
line-timeseries: Time Series Line Plot
3-
Library: plotnine 0.15.2 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-26
3+
Library: plotnine 0.15.4 | Python 3.13.13
4+
Quality: 92/100 | Updated: 2026-05-09
55
"""
66

7+
import os
8+
79
import numpy as np
810
import pandas as pd
911
from mizani.breaks import breaks_date
1012
from mizani.labels import label_date
1113
from plotnine import (
1214
aes,
1315
element_line,
16+
element_rect,
1417
element_text,
1518
geom_line,
1619
geom_point,
@@ -22,36 +25,51 @@
2225
)
2326

2427

25-
# Data: Daily stock prices over one year
28+
THEME = os.getenv("ANYPLOT_THEME", "light")
29+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
30+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
31+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
32+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
33+
BRAND = "#009E73"
34+
35+
# Data: Bitcoin prices over one year with explicit trend and volatility
2636
np.random.seed(42)
27-
dates = pd.date_range(start="2024-01-01", periods=252, freq="B") # Business days
28-
price = 100.0
37+
dates = pd.date_range(start="2023-01-01", periods=365, freq="D")
38+
price = 16500.0
2939
prices = []
30-
for _ in range(252):
31-
price = price * (1 + np.random.randn() * 0.015)
40+
for i in range(365):
41+
# Trend component: upward over the year, with mid-year dip
42+
trend = 20000 + 15000 * np.sin(i / 365 * np.pi * 2) + i * 5
43+
# Volatility: crypto is more volatile than stocks
44+
volatility = price * (1 + np.random.randn() * 0.035)
45+
# Mix trend and volatility
46+
price = 0.7 * trend + 0.3 * volatility
3247
prices.append(price)
3348

3449
df = pd.DataFrame({"date": dates, "price": prices})
3550

3651
# Plot
3752
plot = (
3853
ggplot(df, aes(x="date", y="price"))
39-
+ geom_line(color="#306998", size=1.5, alpha=0.9)
40-
+ geom_point(color="#306998", size=0.8, alpha=0.5)
41-
+ scale_x_datetime(breaks=breaks_date(7), labels=label_date("%b %Y"))
42-
+ labs(title="line-timeseries · plotnine · pyplots.ai", x="Date", y="Stock Price ($)")
54+
+ geom_line(color=BRAND, size=1.5, alpha=0.9)
55+
+ geom_point(color=BRAND, size=0.8, alpha=0.5)
56+
+ scale_x_datetime(breaks=breaks_date(30), labels=label_date("%b"))
57+
+ labs(title="line-timeseries · plotnine · anyplot.ai", x="Date", y="Bitcoin Price (USD)")
4358
+ theme_minimal()
4459
+ theme(
4560
figure_size=(16, 9),
46-
text=element_text(size=14),
47-
axis_title=element_text(size=20),
48-
axis_text=element_text(size=16),
61+
plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
62+
panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
63+
panel_grid_major=element_line(color=INK, size=0.3, alpha=0.10),
64+
panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.05),
65+
panel_border=element_rect(color=INK_SOFT, fill=None),
66+
text=element_text(size=14, color=INK),
67+
axis_title=element_text(size=20, color=INK),
68+
axis_text=element_text(size=16, color=INK_SOFT),
4969
axis_text_x=element_text(angle=45, hjust=1),
50-
plot_title=element_text(size=24),
51-
panel_grid_major=element_line(color="#cccccc", size=0.5, alpha=0.3),
52-
panel_grid_minor=element_line(color="#dddddd", size=0.3, alpha=0.2),
70+
plot_title=element_text(size=24, color=INK),
5371
)
5472
)
5573

5674
# Save
57-
plot.save("plot.png", dpi=300)
75+
plot.save(f"plot-{THEME}.png", dpi=300)

0 commit comments

Comments
 (0)