Skip to content

Commit 1a8a3e4

Browse files
feat(letsplot): implement rug-basic (#5589)
## Implementation: `rug-basic` - python/letsplot Implements the **python/letsplot** version of `rug-basic`. **File:** `plots/rug-basic/implementations/python/letsplot.py` **Parent Issue:** #978 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/25148880653)* --------- 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 0ab6385 commit 1a8a3e4

2 files changed

Lines changed: 187 additions & 143 deletions

File tree

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
rug-basic: Basic Rug Plot
3-
Library: letsplot 4.8.2 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-23
3+
Library: letsplot 4.9.0 | Python 3.13.13
4+
Quality: 87/100 | Updated: 2026-04-30
55
"""
66

7+
import os
8+
79
import numpy as np
810
import pandas as pd
911
from lets_plot import * # noqa: F403
@@ -12,6 +14,13 @@
1214

1315
LetsPlot.setup_html() # noqa: F405
1416

17+
# Theme tokens
18+
THEME = os.getenv("ANYPLOT_THEME", "light")
19+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
20+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
21+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
22+
BRAND = "#009E73" # Okabe-Ito position 1
23+
1524
# Data - Simulated response times with clusters and gaps (realistic scenario)
1625
np.random.seed(42)
1726
cluster1 = np.random.normal(120, 15, 45) # Fast responses ~120ms
@@ -22,37 +31,39 @@
2231

2332
df = pd.DataFrame({"response_time": values})
2433

25-
# Rug data - create short segments at bottom of plot
26-
# Height scaled to be visible but small relative to plot (spec requirement)
27-
rug_y_max = 0.0004 # Small tick height, ~10% of density peak
34+
rug_y_max = 0.0005
2835
df_rug = pd.DataFrame(
2936
{"x": values, "xend": values, "y": np.zeros(len(values)), "yend": np.full(len(values), rug_y_max)}
3037
)
3138

3239
# Plot - Density curve with rug marks along x-axis
3340
plot = (
3441
ggplot(df, aes(x="response_time")) # noqa: F405
35-
+ geom_density(fill="#306998", alpha=0.3, size=1.5, color="#306998") # noqa: F405
42+
+ geom_density(fill=BRAND, alpha=0.25, size=1.5, color=BRAND) # noqa: F405
3643
+ geom_segment( # noqa: F405
3744
aes(x="x", xend="xend", y="y", yend="yend"), # noqa: F405
3845
data=df_rug,
39-
color="#306998",
40-
alpha=0.8,
41-
size=1.2,
46+
color=BRAND,
47+
alpha=0.7,
48+
size=1.5,
49+
)
50+
+ labs( # noqa: F405
51+
x="Response Time (ms)", y="Density", title="rug-basic · letsplot · anyplot.ai"
4252
)
43-
+ labs(x="Response Time (ms)", y="Density", title="rug-basic · letsplot · pyplots.ai") # noqa: F405
4453
+ theme_minimal() # noqa: F405
4554
+ theme( # noqa: F405
46-
axis_title=element_text(size=20), # noqa: F405
47-
axis_text=element_text(size=16), # noqa: F405
48-
plot_title=element_text(size=24), # noqa: F405
49-
panel_grid=element_line(color="#cccccc", size=0.5), # noqa: F405
55+
plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG), # noqa: F405
56+
panel_background=element_rect(fill=PAGE_BG), # noqa: F405
57+
axis_title=element_text(size=20, color=INK), # noqa: F405
58+
axis_text=element_text(size=16, color=INK_SOFT), # noqa: F405
59+
plot_title=element_text(size=24, color=INK), # noqa: F405
60+
panel_grid_major=element_line(color=INK_SOFT, size=0.2), # noqa: F405
61+
panel_grid_minor=element_blank(), # noqa: F405
62+
axis_line=element_line(color=INK_SOFT), # noqa: F405
5063
)
5164
+ ggsize(1600, 900) # noqa: F405
5265
)
5366

54-
# Save PNG (scale 3x to get 4800 x 2700 px)
55-
export_ggsave(plot, filename="plot.png", path=".", scale=3)
56-
57-
# Save HTML for interactive version
58-
export_ggsave(plot, filename="plot.html", path=".")
67+
# Save PNG (scale 3x for 4800x2700) and HTML
68+
export_ggsave(plot, f"plot-{THEME}.png", path=".", scale=3)
69+
export_ggsave(plot, f"plot-{THEME}.html", path=".")

0 commit comments

Comments
 (0)