Skip to content

Commit d6806c4

Browse files
feat(seaborn): implement ecdf-basic (#9483)
## Implementation: `ecdf-basic` - python/seaborn Implements the **python/seaborn** version of `ecdf-basic`. **File:** `plots/ecdf-basic/implementations/python/seaborn.py` **Parent Issue:** #976 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/28160225103)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 503e21f commit d6806c4

2 files changed

Lines changed: 140 additions & 92 deletions

File tree

Lines changed: 39 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
""" anyplot.ai
22
ecdf-basic: Basic ECDF Plot
3-
Library: seaborn 0.13.2 | Python 3.14.4
4-
Quality: 88/100 | Updated: 2026-04-24
3+
Library: seaborn 0.13.2 | Python 3.13.14
4+
Quality: 90/100 | Updated: 2026-06-25
55
"""
66

77
import os
@@ -10,13 +10,16 @@
1010
import seaborn as sns
1111

1212

13-
# Theme tokens
13+
# Theme tokens — Imprint palette + theme-adaptive chrome
1414
THEME = os.getenv("ANYPLOT_THEME", "light")
1515
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
1616
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
1717
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
1818
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
19-
BRAND = "#009E73" # Okabe-Ito position 1
19+
INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F"
20+
21+
# Imprint categorical palette — positions 1, 2, 3 (Adelie, Chinstrap, Gentoo)
22+
IMPRINT_PALETTE = ["#009E73", "#C475FD", "#4467A3"]
2023

2124
sns.set_theme(
2225
style="ticks",
@@ -29,35 +32,54 @@
2932
"xtick.color": INK_SOFT,
3033
"ytick.color": INK_SOFT,
3134
"grid.color": INK,
32-
"grid.alpha": 0.10,
35+
"grid.alpha": 0.12,
3336
"legend.facecolor": ELEVATED_BG,
3437
"legend.edgecolor": INK_SOFT,
3538
},
3639
)
3740

38-
# Data - real-world sample: penguin flipper lengths
39-
penguins = sns.load_dataset("penguins").dropna(subset=["flipper_length_mm"])
41+
# Data penguin flipper lengths by species (deterministic real-world dataset)
42+
penguins = sns.load_dataset("penguins").dropna(subset=["flipper_length_mm", "species"])
4043

41-
# Plot
42-
fig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)
44+
# Plot — multi-hue ecdfplot shows distribution comparison across species
45+
fig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)
4346
ax.set_facecolor(PAGE_BG)
4447

45-
sns.ecdfplot(data=penguins, x="flipper_length_mm", ax=ax, linewidth=3.5, color=BRAND)
48+
sns.ecdfplot(data=penguins, x="flipper_length_mm", hue="species", palette=IMPRINT_PALETTE, linewidth=2.5, ax=ax)
49+
50+
# Percentile reference lines for direct reading of Q1 / median / Q3
51+
for p in (0.25, 0.50, 0.75):
52+
ax.axhline(p, color=INK_MUTED, linewidth=0.7, linestyle="--", alpha=0.55, zorder=0)
4653

4754
# Style
48-
ax.set_xlabel("Flipper Length (mm)", fontsize=20, color=INK)
49-
ax.set_ylabel("Cumulative Proportion", fontsize=20, color=INK)
50-
ax.set_title("Penguin Flipper Lengths · ecdf-basic · seaborn · anyplot.ai", fontsize=24, fontweight="medium", color=INK)
51-
ax.tick_params(axis="both", labelsize=16, colors=INK_SOFT)
55+
title = "Penguin Flipper Lengths · ecdf-basic · python · seaborn · anyplot.ai"
56+
n = len(title)
57+
title_fontsize = round(12 * 67 / n) if n > 67 else 12
58+
ax.set_title(title, fontsize=title_fontsize, fontweight="medium", color=INK)
59+
ax.set_xlabel("Flipper Length (mm)", fontsize=10, color=INK)
60+
ax.set_ylabel("Cumulative Proportion", fontsize=10, color=INK)
61+
ax.tick_params(axis="both", labelsize=8, colors=INK_SOFT)
5262
ax.set_ylim(0, 1)
63+
ax.set_yticks([0, 0.25, 0.50, 0.75, 1.0])
5364

5465
ax.spines["top"].set_visible(False)
5566
ax.spines["right"].set_visible(False)
5667
for side in ("left", "bottom"):
5768
ax.spines[side].set_color(INK_SOFT)
5869

59-
ax.grid(True, axis="both", alpha=0.10, linewidth=0.8, color=INK)
70+
ax.yaxis.grid(True, alpha=0.12, linewidth=0.8, color=INK)
6071
ax.set_axisbelow(True)
6172

62-
plt.tight_layout()
63-
plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG)
73+
# Style the auto-generated legend
74+
legend = ax.get_legend()
75+
if legend:
76+
legend.get_frame().set_facecolor(ELEVATED_BG)
77+
legend.get_frame().set_edgecolor(INK_SOFT)
78+
for text in legend.get_texts():
79+
text.set_color(INK_SOFT)
80+
text.set_fontsize(8)
81+
legend.set_title("Species", prop={"size": 8, "weight": "medium"})
82+
legend.get_title().set_color(INK_SOFT)
83+
84+
# Save — bbox_inches must stay default (None) to preserve exact figsize × dpi canvas
85+
plt.savefig(f"plot-{THEME}.png", dpi=400, facecolor=PAGE_BG)

0 commit comments

Comments
 (0)