Skip to content

Commit 3c466b2

Browse files
feat(plotnine): implement ice-basic (#10322)
## Implementation: `ice-basic` - python/plotnine Implements the **python/plotnine** version of `ice-basic`. **File:** `plots/ice-basic/implementations/python/plotnine.py` **Parent Issue:** #5238 --- :robot: *[impl-generate workflow](https://github.com/MarkusNeusinger/anyplot/actions/runs/32077278547)* --------- 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 445e1f1 commit 3c466b2

2 files changed

Lines changed: 118 additions & 88 deletions

File tree

plots/ice-basic/implementations/python/plotnine.py

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
""" anyplot.ai
22
ice-basic: Individual Conditional Expectation (ICE) Plot
3-
Library: plotnine 0.15.4 | Python 3.13.13
4-
Quality: 87/100 | Created: 2026-05-07
3+
Library: plotnine 0.15.8 | Python 3.13.15
4+
Quality: 92/100 | Updated: 2026-08-17
55
"""
66

77
import os
@@ -23,6 +23,7 @@
2323
element_text,
2424
geom_line,
2525
geom_rug,
26+
geom_vline,
2627
ggplot,
2728
labs,
2829
scale_x_continuous,
@@ -36,8 +37,11 @@
3637
PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17"
3738
INK = "#1A1A17" if THEME == "light" else "#F0EFE8"
3839
INK_SOFT = "#4A4A44" if THEME == "light" else "#B8B7B0"
39-
BRAND = "#009E73"
40-
VERMILLION = "#C475FD"
40+
41+
# Imprint palette — first series is always #009E73
42+
IMPRINT_PALETTE = ["#009E73", "#C475FD", "#4467A3", "#BD8233", "#AE3030", "#2ABCCD", "#954477", "#99B314"]
43+
BRAND = IMPRINT_PALETTE[0]
44+
PDP_COLOR = IMPRINT_PALETTE[1]
4145

4246
# Data — synthetic housing dataset
4347
np.random.seed(42)
@@ -79,35 +83,51 @@
7983
ann_x = float(area_grid[ann_idx])
8084
ann_y = float(pdp_df.iloc[ann_idx]["prediction"]) + 25
8185

86+
# Largest single-step jump in the PDP curve — marks the tree-split boundary the model learned
87+
jump_idx = int(pdp_df["prediction"].diff().abs().idxmax())
88+
split_x = float(pdp_df.loc[jump_idx, "feature_value"])
89+
split_label_y = float(pdp_df["prediction"].max()) + 20
90+
8291
# Plot
8392
anyplot_theme = theme(
84-
figure_size=(16, 9),
93+
figure_size=(8, 4.5),
8594
plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),
8695
panel_background=element_rect(fill=PAGE_BG),
87-
panel_grid_major_y=element_line(color=INK, size=0.3, alpha=0.10),
96+
panel_grid_major_y=element_line(color=INK, size=0.3, alpha=0.12),
8897
panel_grid_major_x=element_blank(),
8998
panel_grid_minor=element_blank(),
9099
panel_border=element_blank(),
91-
axis_title=element_text(color=INK, size=20),
92-
axis_text=element_text(color=INK_SOFT, size=16),
100+
axis_title=element_text(color=INK, size=10),
101+
axis_text=element_text(color=INK_SOFT, size=8),
93102
axis_line=element_line(color=INK_SOFT),
94-
plot_title=element_text(color=INK, size=24, face="bold"),
103+
plot_title=element_text(color=INK, size=12, face="bold"),
95104
legend_position="none",
96-
plot_margin=0.025,
105+
plot_margin=0.05,
97106
)
98107

99108
plot = (
100109
ggplot(ice_df, aes(x="feature_value", y="prediction", group="observation_id"))
101110
+ geom_line(alpha=0.12, color=BRAND, size=0.5)
111+
+ geom_vline(xintercept=split_x, color=INK_SOFT, alpha=0.5, linetype="dashed", size=0.4)
102112
+ geom_line(
103-
data=pdp_df, mapping=aes(x="feature_value", y="prediction"), color=VERMILLION, size=2.5, inherit_aes=False
113+
data=pdp_df, mapping=aes(x="feature_value", y="prediction"), color=PDP_COLOR, size=2.5, inherit_aes=False
104114
)
105115
+ geom_rug(data=rug_df, mapping=aes(x="feature_value"), color=INK_SOFT, alpha=0.4, sides="b", inherit_aes=False)
106-
+ annotate("text", x=ann_x, y=ann_y, label="PDP (avg effect)", color=VERMILLION, size=14)
116+
+ annotate("text", x=ann_x, y=ann_y, label="PDP (avg effect)", color=PDP_COLOR, size=4.0, fontweight="bold")
117+
+ annotate(
118+
"text",
119+
x=split_x,
120+
y=split_label_y,
121+
label=f"model split ~{split_x:.0f} sq ft",
122+
color=INK_SOFT,
123+
size=3.2,
124+
fontstyle="italic",
125+
ha="center",
126+
)
107127
+ scale_x_continuous(breaks=[1000, 1500, 2000, 2500, 3000, 3500])
108128
+ labs(x="House Area (sq ft)", y="Predicted Price ($000s)", title="ice-basic · plotnine · anyplot.ai")
109129
+ anyplot_theme
110130
)
111131

112132
# Save
113-
plot.save(f"plot-{THEME}.png", dpi=300, width=16, height=9)
133+
plot.save(f"plot-{THEME}.png", dpi=400, width=8, height=4.5, units="in")

0 commit comments

Comments
 (0)