Skip to content

Commit 2d94cdf

Browse files
feat(plotly): implement ecdf-basic (#5356)
## Implementation: `ecdf-basic` - python/plotly Implements the **python/plotly** version of `ecdf-basic`. **File:** `plots/ecdf-basic/implementations/python/plotly.py` **Parent Issue:** #976 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/24890176082)* --------- 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 06f2327 commit 2d94cdf

2 files changed

Lines changed: 241 additions & 147 deletions

File tree

Lines changed: 70 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,53 +1,94 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
ecdf-basic: Basic ECDF Plot
3-
Library: plotly 6.5.0 | Python 3.13.11
4-
Quality: 92/100 | Created: 2025-12-23
3+
Library: plotly 6.7.0 | Python 3.14.4
4+
Quality: 88/100 | Updated: 2026-04-24
55
"""
66

7+
import os
8+
79
import numpy as np
810
import plotly.graph_objects as go
911

1012

11-
# Data
12-
np.random.seed(42)
13-
values = np.random.normal(loc=50, scale=15, size=200)
13+
# Theme tokens
14+
THEME = os.getenv("ANYPLOT_THEME", "light")
15+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
16+
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
17+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
18+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
19+
GRID = "rgba(26,26,23,0.10)" if THEME == "light" else "rgba(240,239,232,0.10)"
20+
BRAND = "#009E73" # Okabe-Ito position 1 — always first series
1421

15-
# Compute ECDF
16-
sorted_values = np.sort(values)
17-
ecdf_y = np.arange(1, len(sorted_values) + 1) / len(sorted_values)
22+
# Data: marathon finishing times (minutes) for 300 runners
23+
np.random.seed(42)
24+
n_runners = 300
25+
finish_times = np.random.normal(loc=240, scale=32, size=n_runners)
1826

19-
# Create figure
20-
fig = go.Figure()
27+
# ECDF
28+
sorted_times = np.sort(finish_times)
29+
cumulative_proportion = np.arange(1, n_runners + 1) / n_runners
2130

22-
fig.add_trace(
31+
# Plot
32+
fig = go.Figure(
2333
go.Scatter(
24-
x=sorted_values, y=ecdf_y, mode="lines", line={"color": "#306998", "width": 4, "shape": "hv"}, name="ECDF"
34+
x=sorted_times,
35+
y=cumulative_proportion,
36+
mode="lines",
37+
line={"color": BRAND, "width": 3.5, "shape": "hv"},
38+
hovertemplate=("<b>Finish Time</b>: %{x:.1f} min<br><b>Cumulative</b>: %{y:.1%}<br><extra></extra>"),
39+
showlegend=False,
2540
)
2641
)
2742

28-
# Layout
43+
# Style
2944
fig.update_layout(
30-
title={"text": "ecdf-basic · plotly · pyplots.ai", "font": {"size": 48}},
45+
title={
46+
"text": "Marathon Finishing Times · ecdf-basic · plotly · anyplot.ai",
47+
"font": {"size": 28, "color": INK},
48+
"x": 0.5,
49+
"xanchor": "center",
50+
"y": 0.95,
51+
},
3152
xaxis={
32-
"title": {"text": "Value", "font": {"size": 36}},
33-
"tickfont": {"size": 28},
34-
"showgrid": True,
53+
"title": {"text": "Finishing Time (minutes)", "font": {"size": 22, "color": INK}, "standoff": 12},
54+
"tickfont": {"size": 18, "color": INK_SOFT},
55+
"gridcolor": GRID,
3556
"gridwidth": 1,
36-
"gridcolor": "rgba(0,0,0,0.1)",
57+
"linecolor": INK_SOFT,
58+
"zeroline": False,
59+
"showline": True,
60+
"mirror": False,
61+
"ticksuffix": " min",
3762
},
3863
yaxis={
39-
"title": {"text": "Cumulative Proportion", "font": {"size": 36}},
40-
"tickfont": {"size": 28},
41-
"range": [0, 1],
42-
"showgrid": True,
64+
"title": {"text": "Cumulative Proportion of Runners", "font": {"size": 22, "color": INK}, "standoff": 12},
65+
"tickfont": {"size": 18, "color": INK_SOFT},
66+
"gridcolor": GRID,
4367
"gridwidth": 1,
44-
"gridcolor": "rgba(0,0,0,0.1)",
68+
"linecolor": INK_SOFT,
69+
"zeroline": False,
70+
"showline": True,
71+
"mirror": False,
72+
"range": [0, 1.02],
73+
"tickformat": ".0%",
74+
"dtick": 0.1,
4575
},
46-
template="plotly_white",
47-
showlegend=False,
48-
margin={"l": 100, "r": 50, "t": 120, "b": 100},
76+
paper_bgcolor=PAGE_BG,
77+
plot_bgcolor=PAGE_BG,
78+
font={"color": INK, "family": "Inter, Helvetica Neue, Arial, sans-serif"},
79+
margin={"l": 110, "r": 70, "t": 110, "b": 90},
80+
hovermode="x unified",
81+
hoverlabel={"bgcolor": ELEVATED_BG, "bordercolor": INK_SOFT, "font": {"color": INK, "size": 15}, "align": "left"},
4982
)
5083

5184
# Save
52-
fig.write_image("plot.png", width=1600, height=900, scale=3)
53-
fig.write_html("plot.html")
85+
fig.write_image(f"plot-{THEME}.png", width=1600, height=900, scale=3)
86+
fig.write_html(
87+
f"plot-{THEME}.html",
88+
include_plotlyjs="cdn",
89+
config={
90+
"displaylogo": False,
91+
"modeBarButtonsToRemove": ["lasso2d", "select2d", "autoScale2d"],
92+
"toImageButtonOptions": {"format": "png", "filename": "ecdf-basic-plotly"},
93+
},
94+
)

0 commit comments

Comments
 (0)