Skip to content

Commit 6018975

Browse files
feat(letsplot): implement line-timeseries (#6123)
## Implementation: `line-timeseries` - python/letsplot Implements the **python/letsplot** version of `line-timeseries`. **File:** `plots/line-timeseries/implementations/python/letsplot.py` **Parent Issue:** #2006 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/25590562472)* --------- 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 29b0138 commit 6018975

2 files changed

Lines changed: 189 additions & 141 deletions

File tree

Lines changed: 48 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,74 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
line-timeseries: Time Series Line Plot
3-
Library: letsplot 4.8.2 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-26
3+
Library: letsplot 4.9.0 | Python 3.13.13
4+
Quality: 89/100 | Updated: 2026-05-09
55
"""
66

7+
import os
8+
79
import numpy as np
810
import pandas as pd
911
from lets_plot import *
1012

1113

1214
LetsPlot.setup_html()
1315

16+
# Theme tokens
17+
THEME = os.getenv("ANYPLOT_THEME", "light")
18+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
19+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
20+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
21+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
22+
ACCENT_SOFT = "#D4A574" if THEME == "light" else "#8B7355"
23+
BRAND = "#009E73"
24+
1425
# Data - Daily temperature readings over one year
1526
np.random.seed(42)
1627
dates = pd.date_range(start="2024-01-01", periods=365, freq="D")
1728

1829
# Simulate realistic temperature data with seasonal pattern
1930
day_of_year = np.arange(365)
20-
seasonal_pattern = 15 * np.sin(2 * np.pi * (day_of_year - 80) / 365) # Peak in summer
21-
baseline = 12 # Average temperature
22-
noise = np.random.randn(365) * 3 # Daily variation
31+
seasonal_pattern = 15 * np.sin(2 * np.pi * (day_of_year - 80) / 365)
32+
baseline = 12
33+
noise = np.random.randn(365) * 3
2334
temperature = baseline + seasonal_pattern + noise
2435

2536
df = pd.DataFrame({"date": dates, "temperature": temperature})
2637

27-
# Create plot
38+
# Find peak and trough for visual emphasis
39+
max_idx = df["temperature"].idxmax()
40+
min_idx = df["temperature"].idxmin()
41+
extremes = pd.DataFrame([df.iloc[max_idx], df.iloc[min_idx]])
42+
43+
# Theme-adaptive styling with enhanced refinement
44+
anyplot_theme = theme(
45+
plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
46+
panel_background=element_rect(fill=PAGE_BG),
47+
panel_grid_major=element_line(color=INK_SOFT, size=0.25, linetype="solid"),
48+
panel_grid_minor=element_blank(),
49+
axis_title=element_text(size=20, color=INK, face="bold"),
50+
axis_text=element_text(size=16, color=INK_SOFT),
51+
axis_text_x=element_text(angle=45, hjust=1),
52+
plot_title=element_text(size=24, color=INK, face="bold"),
53+
legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),
54+
legend_text=element_text(size=16, color=INK_SOFT),
55+
legend_title=element_text(size=16, color=INK),
56+
axis_line=element_line(color=INK_SOFT, size=0.4),
57+
)
58+
59+
# Create plot with layered visual hierarchy
2860
plot = (
2961
ggplot(df, aes(x="date", y="temperature"))
30-
+ geom_line(color="#306998", size=1.5, alpha=0.9)
31-
+ labs(x="Date", y="Temperature (°C)", title="line-timeseries · letsplot · pyplots.ai")
32-
+ theme_minimal()
33-
+ theme(
34-
plot_title=element_text(size=24, face="bold"),
35-
axis_title=element_text(size=20),
36-
axis_text=element_text(size=16),
37-
axis_text_x=element_text(angle=45),
38-
panel_grid_major=element_line(color="#CCCCCC", size=0.5),
39-
panel_grid_minor=element_line(color="#EEEEEE", size=0.3),
40-
)
41-
+ ggsize(1600, 900)
62+
+ geom_smooth(method="loess", span=0.15, color=ACCENT_SOFT, size=1.2, alpha=0.5, se=False)
63+
+ geom_line(color=BRAND, size=1.0, alpha=0.8)
64+
+ geom_point(color=BRAND, size=1.5, alpha=0.6)
65+
+ geom_point(data=extremes, color=BRAND, size=3.5, alpha=0.95)
66+
+ labs(x="Date", y="Temperature (°C)", title="line-timeseries · letsplot · anyplot.ai")
4267
+ scale_x_datetime(format="%b %Y")
68+
+ ggsize(1600, 900)
69+
+ anyplot_theme
4370
)
4471

4572
# Save
46-
ggsave(plot, "plot.png", path=".", scale=3)
47-
ggsave(plot, "plot.html", path=".")
73+
ggsave(plot, f"plot-{THEME}.png", path=".", w=4800, h=2700, unit="px", dpi=100)
74+
ggsave(plot, f"plot-{THEME}.html", path=".")

0 commit comments

Comments
 (0)