Skip to content

Commit 026d9b1

Browse files
feat(matplotlib): implement scatter-marginal (#6124)
## Implementation: `scatter-marginal` - python/matplotlib Implements the **python/matplotlib** version of `scatter-marginal`. **File:** `plots/scatter-marginal/implementations/python/matplotlib.py` **Parent Issue:** #2005 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/25592616567)* --------- Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
1 parent 6018975 commit 026d9b1

2 files changed

Lines changed: 204 additions & 161 deletions

File tree

Lines changed: 52 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,60 +1,81 @@
1-
""" pyplots.ai
1+
""" anyplot.ai
22
scatter-marginal: Scatter Plot with Marginal Distributions
3-
Library: matplotlib 3.10.8 | Python 3.13.11
4-
Quality: 91/100 | Created: 2025-12-26
3+
Library: matplotlib 3.10.9 | Python 3.13.13
4+
Quality: 89/100 | Updated: 2026-05-09
55
"""
66

7+
import os
8+
79
import matplotlib.pyplot as plt
810
import numpy as np
911
from matplotlib.gridspec import GridSpec
1012

1113

14+
# Theme tokens
15+
THEME = os.getenv("ANYPLOT_THEME", "light")
16+
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
17+
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
18+
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
19+
BRAND = "#009E73"
20+
1221
# Data - correlated bivariate data with realistic pattern
1322
np.random.seed(42)
1423
n = 200
1524

16-
# Create correlated data with some structure
17-
x = np.concatenate(
18-
[
19-
np.random.normal(30, 8, n // 2), # First cluster
20-
np.random.normal(60, 10, n // 2), # Second cluster
21-
]
22-
)
23-
y = 0.7 * x + np.random.normal(0, 8, n) + 10 # Linear relationship with noise
25+
# Create correlated data with bimodal structure
26+
x = np.concatenate([np.random.normal(30, 8, n // 2), np.random.normal(60, 10, n // 2)])
27+
y = 0.7 * x + np.random.normal(0, 8, n) + 10
2428

2529
# Create figure with GridSpec for layout
26-
fig = plt.figure(figsize=(16, 9))
30+
fig = plt.figure(figsize=(16, 9), facecolor=PAGE_BG)
2731
gs = GridSpec(4, 4, figure=fig, hspace=0.05, wspace=0.05)
2832

2933
# Main scatter plot (lower-left, 3x3)
30-
ax_main = fig.add_subplot(gs[1:4, 0:3])
31-
ax_main.scatter(x, y, s=120, alpha=0.65, color="#306998", edgecolors="white", linewidth=0.5)
32-
ax_main.set_xlabel("X Value", fontsize=20)
33-
ax_main.set_ylabel("Y Value", fontsize=20)
34-
ax_main.tick_params(axis="both", labelsize=16)
35-
ax_main.grid(True, alpha=0.3, linestyle="--")
34+
ax_main = fig.add_subplot(gs[1:4, 0:3], facecolor=PAGE_BG)
35+
ax_main.scatter(x, y, s=100, alpha=0.65, color=BRAND, edgecolors=PAGE_BG, linewidth=0.5)
36+
ax_main.set_xlabel("Feature A", fontsize=20, color=INK)
37+
ax_main.set_ylabel("Feature B", fontsize=20, color=INK)
38+
ax_main.tick_params(axis="both", labelsize=16, colors=INK_SOFT)
39+
ax_main.yaxis.grid(True, alpha=0.10, linewidth=0.8, color=INK)
40+
for s in ("left", "bottom"):
41+
ax_main.spines[s].set_color(INK_SOFT)
42+
ax_main.spines["top"].set_visible(False)
43+
ax_main.spines["right"].set_visible(False)
3644

3745
# Top marginal histogram (aligned with main x-axis)
38-
ax_top = fig.add_subplot(gs[0, 0:3], sharex=ax_main)
39-
ax_top.hist(x, bins=25, color="#306998", alpha=0.7, edgecolor="white", linewidth=0.8)
40-
ax_top.tick_params(axis="x", labelbottom=False)
41-
ax_top.tick_params(axis="y", labelsize=14)
42-
ax_top.set_ylabel("Count", fontsize=16)
46+
ax_top = fig.add_subplot(gs[0, 0:3], sharex=ax_main, facecolor=PAGE_BG)
47+
ax_top.hist(x, bins=25, color=BRAND, alpha=0.5, edgecolor=PAGE_BG, linewidth=0.5)
48+
ax_top.tick_params(axis="x", labelbottom=False, colors=INK_SOFT)
49+
ax_top.tick_params(axis="y", labelsize=14, colors=INK_SOFT)
50+
ax_top.set_ylabel("Count", fontsize=16, color=INK)
4351
ax_top.spines["top"].set_visible(False)
4452
ax_top.spines["right"].set_visible(False)
53+
for s in ("left", "bottom"):
54+
ax_top.spines[s].set_color(INK_SOFT)
55+
ax_top.yaxis.grid(True, alpha=0.10, linewidth=0.8, color=INK)
4556

4657
# Right marginal histogram (aligned with main y-axis)
47-
ax_right = fig.add_subplot(gs[1:4, 3], sharey=ax_main)
48-
ax_right.hist(y, bins=25, orientation="horizontal", color="#306998", alpha=0.7, edgecolor="white", linewidth=0.8)
49-
ax_right.tick_params(axis="y", labelleft=False)
50-
ax_right.tick_params(axis="x", labelsize=14)
51-
ax_right.set_xlabel("Count", fontsize=16)
58+
ax_right = fig.add_subplot(gs[1:4, 3], sharey=ax_main, facecolor=PAGE_BG)
59+
ax_right.hist(y, bins=25, orientation="horizontal", color=BRAND, alpha=0.5, edgecolor=PAGE_BG, linewidth=0.5)
60+
ax_right.tick_params(axis="y", labelleft=False, colors=INK_SOFT)
61+
ax_right.tick_params(axis="x", labelsize=14, colors=INK_SOFT)
62+
ax_right.set_xlabel("Count", fontsize=16, color=INK)
5263
ax_right.spines["top"].set_visible(False)
5364
ax_right.spines["right"].set_visible(False)
65+
for s in ("left", "bottom"):
66+
ax_right.spines[s].set_color(INK_SOFT)
67+
ax_right.xaxis.grid(True, alpha=0.10, linewidth=0.8, color=INK)
5468

55-
# Title in the top-right corner area
69+
# Title
5670
fig.text(
57-
0.98, 0.98, "scatter-marginal · matplotlib · pyplots.ai", fontsize=24, ha="right", va="top", fontweight="normal"
71+
0.5,
72+
0.98,
73+
"scatter-marginal · matplotlib · anyplot.ai",
74+
fontsize=24,
75+
ha="center",
76+
va="top",
77+
color=INK,
78+
fontweight="medium",
5879
)
5980

60-
plt.savefig("plot.png", dpi=300, bbox_inches="tight", facecolor="white")
81+
plt.savefig(f"plot-{THEME}.png", dpi=300, bbox_inches="tight", facecolor=PAGE_BG)

0 commit comments

Comments
 (0)