|
1 | 1 | """ anyplot.ai |
2 | 2 | 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 |
5 | 5 | """ |
6 | 6 |
|
7 | 7 | import os |
|
23 | 23 | element_text, |
24 | 24 | geom_line, |
25 | 25 | geom_rug, |
| 26 | + geom_vline, |
26 | 27 | ggplot, |
27 | 28 | labs, |
28 | 29 | scale_x_continuous, |
|
36 | 37 | PAGE_BG = "#FAF8F1" if THEME == "light" else "#1A1A17" |
37 | 38 | INK = "#1A1A17" if THEME == "light" else "#F0EFE8" |
38 | 39 | 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] |
41 | 45 |
|
42 | 46 | # Data — synthetic housing dataset |
43 | 47 | np.random.seed(42) |
|
79 | 83 | ann_x = float(area_grid[ann_idx]) |
80 | 84 | ann_y = float(pdp_df.iloc[ann_idx]["prediction"]) + 25 |
81 | 85 |
|
| 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 | + |
82 | 91 | # Plot |
83 | 92 | anyplot_theme = theme( |
84 | | - figure_size=(16, 9), |
| 93 | + figure_size=(8, 4.5), |
85 | 94 | plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG), |
86 | 95 | 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), |
88 | 97 | panel_grid_major_x=element_blank(), |
89 | 98 | panel_grid_minor=element_blank(), |
90 | 99 | 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), |
93 | 102 | 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"), |
95 | 104 | legend_position="none", |
96 | | - plot_margin=0.025, |
| 105 | + plot_margin=0.05, |
97 | 106 | ) |
98 | 107 |
|
99 | 108 | plot = ( |
100 | 109 | ggplot(ice_df, aes(x="feature_value", y="prediction", group="observation_id")) |
101 | 110 | + 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) |
102 | 112 | + 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 |
104 | 114 | ) |
105 | 115 | + 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 | + ) |
107 | 127 | + scale_x_continuous(breaks=[1000, 1500, 2000, 2500, 3000, 3500]) |
108 | 128 | + labs(x="House Area (sq ft)", y="Predicted Price ($000s)", title="ice-basic · plotnine · anyplot.ai") |
109 | 129 | + anyplot_theme |
110 | 130 | ) |
111 | 131 |
|
112 | 132 | # 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