Skip to content

Commit bd81ff4

Browse files
feat(seaborn): implement errorbar-basic (#9517)
## Implementation: `errorbar-basic` - python/seaborn Implements the **python/seaborn** version of `errorbar-basic`. **File:** `plots/errorbar-basic/implementations/python/seaborn.py` **Parent Issue:** #973 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/28472936805)* --------- 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 eee5707 commit bd81ff4

2 files changed

Lines changed: 141 additions & 94 deletions

File tree

Lines changed: 48 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
""" anyplot.ai
22
errorbar-basic: Basic Error Bar Plot
3-
Library: seaborn 0.13.2 | Python 3.14.4
4-
Quality: 89/100 | Updated: 2026-04-25
3+
Library: seaborn 0.13.2 | Python 3.13.14
4+
Quality: 88/100 | Updated: 2026-06-30
55
"""
66

77
import os
88

9+
import matplotlib.patches as mpatches
910
import matplotlib.pyplot as plt
1011
import numpy as np
1112
import pandas as pd
@@ -17,20 +18,22 @@
1718
ELEVATED_BG = "#FFFDF6" if THEME == "light" else "#242420"
1819
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
1920
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
21+
INK_MUTED = "#6B6A63" if THEME == "light" else "#A8A79F"
2022

23+
# Imprint palette
2124
IMPRINT = ["#009E73", "#C475FD", "#4467A3", "#BD8233", "#AE3030", "#2ABCCD", "#954477"]
2225
BRAND = IMPRINT[0]
2326
ACCENT = IMPRINT[1]
2427

25-
# Clinical trial: symptom reduction (%) measured for each treatment group
28+
# Clinical trial: symptom reduction (%) by dose group (n=30 per group)
2629
np.random.seed(42)
27-
categories = ["Control", "Treatment A", "Treatment B", "Treatment C", "Treatment D", "Treatment E"]
28-
means = [45.2, 52.8, 61.3, 48.7, 57.4, 43.1]
29-
stds = [4.5, 6.2, 5.8, 7.1, 4.9, 5.5]
30+
categories = ["Control", "Placebo", "10 mg", "25 mg", "50 mg", "100 mg"]
31+
means = [45.2, 46.8, 52.3, 57.4, 61.3, 58.9]
32+
stds = [4.5, 5.1, 6.2, 4.9, 5.8, 7.1]
3033
n_per_group = 30
3134

3235
records = [
33-
{"Treatment": cat, "Symptom Reduction (%)": value}
36+
{"Dose": cat, "Symptom Reduction (%)": value}
3437
for cat, mu, sigma in zip(categories, means, stds, strict=True)
3538
for value in np.random.normal(mu, sigma, n_per_group)
3639
]
@@ -50,38 +53,63 @@
5053
"xtick.color": INK_SOFT,
5154
"ytick.color": INK_SOFT,
5255
"grid.color": INK,
53-
"grid.alpha": 0.10,
56+
"grid.alpha": 0.15,
5457
"legend.facecolor": ELEVATED_BG,
5558
"legend.edgecolor": INK_SOFT,
5659
},
5760
)
5861

59-
fig, ax = plt.subplots(figsize=(16, 9))
62+
fig, ax = plt.subplots(figsize=(8, 4.5), dpi=400)
6063

6164
sns.barplot(
6265
data=df,
63-
x="Treatment",
66+
x="Dose",
6467
y="Symptom Reduction (%)",
65-
hue="Treatment",
68+
hue="Dose",
6669
palette=palette,
6770
legend=False,
6871
errorbar="sd",
6972
capsize=0.25,
70-
err_kws={"color": INK, "linewidth": 2.5},
73+
err_kws={"color": INK, "linewidth": 1.5},
7174
edgecolor=INK_SOFT,
72-
linewidth=1.0,
75+
linewidth=0.6,
7376
ax=ax,
7477
)
7578

76-
ax.set_xlabel("Treatment Group", fontsize=20)
77-
ax.set_ylabel("Symptom Reduction (%)", fontsize=20)
78-
ax.set_title("errorbar-basic · seaborn · anyplot.ai", fontsize=24, fontweight="medium", color=INK)
79-
ax.tick_params(axis="both", labelsize=16)
80-
ax.yaxis.grid(True)
79+
ax.set_xlabel("Dose Group", fontsize=10)
80+
ax.set_ylabel("Symptom Reduction (%)", fontsize=10)
81+
ax.tick_params(axis="both", labelsize=8)
82+
ax.yaxis.grid(True, alpha=0.15, linewidth=0.8)
8183
ax.xaxis.grid(False)
8284
ax.set_axisbelow(True)
8385
ax.spines["top"].set_visible(False)
8486
ax.spines["right"].set_visible(False)
8587

86-
plt.tight_layout()
87-
plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG)
88+
# Legend explaining the two-color strategy: all groups vs. top performer
89+
brand_patch = mpatches.Patch(color=BRAND, label="Dose group")
90+
accent_patch = mpatches.Patch(color=ACCENT, label=f"Top performer ({top_performer})")
91+
ax.legend(handles=[brand_patch, accent_patch], fontsize=8, framealpha=0.9, loc="lower right")
92+
93+
# Title and subtitle placed in figure coordinates to control vertical spacing precisely
94+
fig.text(
95+
0.5,
96+
0.96,
97+
"errorbar-basic · python · seaborn · anyplot.ai",
98+
ha="center",
99+
va="top",
100+
fontsize=12,
101+
fontweight="medium",
102+
color=INK,
103+
)
104+
fig.text(
105+
0.5,
106+
0.90,
107+
f"Bars show mean ± 1 SD — {top_performer} achieves the highest mean symptom reduction",
108+
ha="center",
109+
va="top",
110+
fontsize=9,
111+
color=INK_MUTED,
112+
)
113+
114+
fig.subplots_adjust(top=0.81, bottom=0.13, left=0.11, right=0.97)
115+
plt.savefig(f"plot-{THEME}.png", dpi=400, facecolor=PAGE_BG)

0 commit comments

Comments
 (0)