{"spec_id":"pdp-basic","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\npdp-basic: Partial Dependence Plot\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 94/100 | Updated: 2026-05-15\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\nfrom sklearn.datasets import make_regression\nfrom sklearn.ensemble import GradientBoostingRegressor\nfrom sklearn.inspection import partial_dependence\n\n\nLetsPlot.setup_html()\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nELEVATED_BG = \"#FFFDF6\" if THEME == \"light\" else \"#242420\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Okabe-Ito colors\nBRAND = \"#009E73\"\nACCENT = \"#C475FD\"\n\n# Train a model for partial dependence\nnp.random.seed(42)\nX, y = make_regression(n_samples=500, n_features=5, noise=20, random_state=42)\nfeature_names = [\"Temperature\", \"Humidity\", \"Pressure\", \"WindSpeed\", \"Altitude\"]\n\nmodel = GradientBoostingRegressor(n_estimators=100, max_depth=4, random_state=42)\nmodel.fit(X, y)\n\n# Compute partial dependence for Temperature (feature 0)\nfeature_idx = 0\nfeature_name = feature_names[feature_idx]\npdp_result = partial_dependence(model, X, features=[feature_idx], kind=\"both\", grid_resolution=80)\n\nfeature_values = pdp_result[\"grid_values\"][0]\navg_pd = pdp_result[\"average\"][0]\n\n# Get individual conditional expectations (ICE) for uncertainty\nice_lines = pdp_result[\"individual\"][0]\nlower_bound = np.percentile(ice_lines, 10, axis=0)\nupper_bound = np.percentile(ice_lines, 90, axis=0)\n\n# Create DataFrame for plotting\ndf_pdp = pd.DataFrame(\n    {\"feature_value\": feature_values, \"partial_dependence\": avg_pd, \"lower\": lower_bound, \"upper\": upper_bound}\n)\n\n# Sample ICE lines for visualization (show a subset)\nn_ice_lines = 50\nice_indices = np.random.choice(ice_lines.shape[0], n_ice_lines, replace=False)\nice_data = []\nfor i, idx in enumerate(ice_indices):\n    for j, fv in enumerate(feature_values):\n        ice_data.append({\"feature_value\": fv, \"ice_value\": ice_lines[idx, j], \"line_id\": i})\ndf_ice = pd.DataFrame(ice_data)\n\n# Get rug data (sample of training feature values for distribution)\nrug_sample = np.random.choice(X[:, feature_idx], size=100, replace=False)\nrug_height = (avg_pd.max() - avg_pd.min()) * 0.08\ny_min = avg_pd.min() - rug_height / 2\ny_max = avg_pd.min() + rug_height / 2\ndf_rug = pd.DataFrame(\n    {\"x\": rug_sample, \"y_start\": np.full(len(rug_sample), y_min), \"y_end\": np.full(len(rug_sample), y_max)}\n)\n\n# Custom theme\nanyplot_theme = theme(\n    plot_background=element_rect(fill=PAGE_BG, color=PAGE_BG),\n    panel_background=element_rect(fill=PAGE_BG),\n    panel_grid_major=element_line(color=INK, size=0.2),\n    panel_grid_minor=element_blank(),\n    axis_title=element_text(color=INK, size=20),\n    axis_text=element_text(color=INK_SOFT, size=16),\n    axis_line=element_line(color=INK_SOFT, size=0.5),\n    plot_title=element_text(color=INK, size=24, face=\"bold\"),\n    legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n    legend_text=element_text(color=INK_SOFT, size=16),\n    legend_title=element_text(color=INK, size=16),\n)\n\n# Create the partial dependence plot\nplot = (\n    ggplot()\n    + geom_ribbon(aes(x=\"feature_value\", ymin=\"lower\", ymax=\"upper\", fill=\"Confidence Band\"), data=df_pdp, alpha=0.25)\n    + geom_line(\n        aes(x=\"feature_value\", y=\"ice_value\", group=\"line_id\", color=\"Individual\"), data=df_ice, alpha=0.2, size=0.5\n    )\n    + geom_line(aes(x=\"feature_value\", y=\"partial_dependence\", color=\"Main PDP\"), data=df_pdp, size=2.5)\n    + geom_segment(\n        aes(x=\"x\", y=\"y_start\", xend=\"x\", yend=\"y_end\", color=\"Data Distribution\"), data=df_rug, alpha=0.6, size=1.2\n    )\n    + scale_color_manual(values={\"Main PDP\": BRAND, \"Individual\": ACCENT, \"Data Distribution\": ACCENT})\n    + scale_fill_manual(values={\"Confidence Band\": ACCENT})\n    + labs(\n        x=f\"{feature_name} (standardized)\",\n        y=\"Partial Dependence (predicted outcome)\",\n        title=\"pdp-basic · letsplot · anyplot.ai\",\n        color=\"Elements\",\n        fill=\"\",\n    )\n    + anyplot_theme\n    + ggsize(1600, 900)\n    + theme(legend_position=\"top\", legend_direction=\"horizontal\")\n)\n\n# Save as PNG and HTML\nggsave(plot, f\"plot-{THEME}.png\", w=4800, h=2700, unit=\"px\", path=\".\")\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}