Skip to content

Commit 4b5d534

Browse files
feat(letsplot): implement ecdf-basic
Regen from quality 87. Addressed: - Canvas: ggsize(800, 450) + scale=4 → exact 3200×1800 (was ggsize(1600, 900) + scale=3 → 4800×2700) - Title: fixed to 3-part format "ecdf-basic · python · letsplot · anyplot.ai" (removed descriptive prefix, added language token) - Grid opacity: pre-blended #D8D7D0/#3A3A36 at ~15% opacity (was #C9C7C1/#565551 at ~22%) - Font sizes: aligned to letsplot.md canonical 16/12/10 pt at scale=4 (was 24/20/16 at wrong scale) - LM-02: added layer_tooltips() for interactive HTML response time display
1 parent d6806c4 commit 4b5d534

1 file changed

Lines changed: 22 additions & 18 deletions

File tree

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
""" anyplot.ai
1+
"""anyplot.ai
22
ecdf-basic: Basic ECDF Plot
3-
Library: letsplot 4.9.0 | Python 3.14.4
4-
Quality: 87/100 | Updated: 2026-04-24
3+
Library: letsplot | Python 3.14
4+
Quality: pending | Created: 2026-06-25
55
"""
66

77
import os
@@ -18,6 +18,7 @@
1818
ggplot,
1919
ggsize,
2020
labs,
21+
layer_tooltips,
2122
scale_y_continuous,
2223
stat_ecdf,
2324
theme,
@@ -31,44 +32,47 @@
3132
# Theme tokens
3233
THEME = os.getenv("ANYPLOT_THEME", "light")
3334
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
35+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
3436
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
3537
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
36-
GRID = "#C9C7C1" if THEME == "light" else "#565551"
38+
# Imprint palette — grid at ~15% opacity, pre-blended with PAGE_BG
39+
GRID = "#D8D7D0" if THEME == "light" else "#3A3A36"
3740
BRAND = "#009E73"
3841

39-
# Data — Web service response times (ms) with mixed distribution
42+
# Data — web service response times (ms) with bimodal distribution
4043
np.random.seed(42)
4144
response_times = np.concatenate(
4245
[np.random.exponential(scale=50, size=150), np.random.normal(loc=200, scale=30, size=50)]
4346
)
4447
df = pd.DataFrame({"response_time": response_times})
4548

46-
# Plot — ECDF using stat_ecdf with step geometry
49+
# Title — 3-part format, 44 chars (< 67 baseline, no scaling needed)
50+
title = "ecdf-basic · python · letsplot · anyplot.ai"
51+
52+
# Plot — ECDF step function with interactive tooltips (lets-plot HTML capability)
4753
plot = (
4854
ggplot(df, aes(x="response_time"))
49-
+ stat_ecdf(geom="step", color=BRAND, size=2)
50-
+ labs(
51-
x="Response Time (ms)",
52-
y="Cumulative Proportion",
53-
title="Web Service Response Times · ecdf-basic · letsplot · anyplot.ai",
55+
+ stat_ecdf(
56+
geom="step", color=BRAND, size=1.5, tooltips=layer_tooltips().line("Response Time: @response_time{,.0f} ms")
5457
)
58+
+ labs(x="Response Time (ms)", y="Cumulative Proportion", title=title)
5559
+ scale_y_continuous(limits=[0, 1], breaks=[0, 0.25, 0.5, 0.75, 1.0])
56-
+ ggsize(1600, 900)
60+
+ ggsize(800, 450)
5761
+ theme_minimal()
5862
+ theme(
5963
plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
6064
panel_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
61-
legend_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
62-
panel_grid_major=element_line(color=GRID, size=0.6),
65+
legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),
66+
panel_grid_major=element_line(color=GRID, size=0.5),
6367
panel_grid_minor=element_blank(),
6468
axis_line=element_line(color=INK_SOFT, size=0.6),
6569
axis_ticks=element_line(color=INK_SOFT, size=0.5),
66-
axis_text=element_text(size=16, color=INK_SOFT),
67-
axis_title=element_text(size=20, color=INK),
68-
plot_title=element_text(size=24, color=INK),
70+
axis_text=element_text(size=10, color=INK_SOFT),
71+
axis_title=element_text(size=12, color=INK),
72+
plot_title=element_text(size=16, color=INK),
6973
)
7074
)
7175

7276
# Save
73-
ggsave(plot, filename=f"plot-{THEME}.png", path=".", scale=3)
77+
ggsave(plot, filename=f"plot-{THEME}.png", path=".", scale=4)
7478
ggsave(plot, filename=f"plot-{THEME}.html", path=".")

0 commit comments

Comments
 (0)