{"spec_id":"pdp-basic","library":"pygal","language":"python","code":"\"\"\" anyplot.ai\npdp-basic: Partial Dependence Plot\nLibrary: pygal 3.1.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-15\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pygal\nfrom pygal.style import Style\nfrom sklearn.datasets import make_regression\nfrom sklearn.ensemble import GradientBoostingRegressor\nfrom sklearn.inspection import partial_dependence\n\n\n# Theme tokens\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\nIMPRINT = (\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\")\n\n# Generate data and train model\nnp.random.seed(42)\nX, y = make_regression(n_samples=500, n_features=5, noise=10, random_state=42)\nmodel = GradientBoostingRegressor(n_estimators=50, max_depth=3, random_state=42)\nmodel.fit(X, y)\n\n# Calculate partial dependence for feature 0\nfeature_idx = 0\npdp_result = partial_dependence(model, X, features=[feature_idx], kind=\"average\", grid_resolution=100)\nfeature_values = pdp_result[\"grid_values\"][0]\npd_values = pdp_result[\"average\"][0]\n\n# Calculate confidence interval using individual predictions\npdp_individual = partial_dependence(model, X, features=[feature_idx], kind=\"individual\", grid_resolution=100)\nindividual_preds = pdp_individual[\"individual\"][0]\npd_std = np.std(individual_preds, axis=0)\nci_lower = pd_values - 1.96 * pd_std / np.sqrt(len(X))\nci_upper = pd_values + 1.96 * pd_std / np.sqrt(len(X))\n\n# Custom style for theme-adaptive rendering\ncustom_style = Style(\n    background=PAGE_BG,\n    plot_background=PAGE_BG,\n    foreground=INK,\n    foreground_strong=INK,\n    foreground_subtle=INK_MUTED,\n    colors=IMPRINT,\n    title_font_size=28,\n    label_font_size=22,\n    major_label_font_size=18,\n    legend_font_size=16,\n    value_font_size=14,\n    stroke_width=3,\n)\n\n# Create XY chart for PDP line plot\nchart = pygal.XY(\n    width=4800,\n    height=2700,\n    style=custom_style,\n    title=\"pdp-basic · pygal · anyplot.ai\",\n    x_title=\"Feature Value (standardized)\",\n    y_title=\"Partial Dependence\",\n    show_legend=True,\n    legend_at_bottom=True,\n    show_dots=False,\n    stroke_style={\"width\": 4},\n    show_x_guides=True,\n    show_y_guides=True,\n    dots_size=6,\n    margin_bottom=150,\n)\n\n# Create XY data points for main PDP line\npdp_points = [(float(x), float(y)) for x, y in zip(feature_values, pd_values, strict=True)]\n\n# Create confidence interval points\nci_upper_points = [(float(x), float(y)) for x, y in zip(feature_values, ci_upper, strict=True)]\nci_lower_points = [(float(x), float(y)) for x, y in zip(feature_values, ci_lower, strict=True)]\n\n# Add data series\nchart.add(\"Partial Dependence\", pdp_points, stroke_style={\"width\": 5})\nchart.add(\"95% CI Upper\", ci_upper_points, stroke_style={\"width\": 2, \"dasharray\": \"8,4\"})\nchart.add(\"95% CI Lower\", ci_lower_points, stroke_style={\"width\": 2, \"dasharray\": \"8,4\"})\n\n# Add rug plot showing training data distribution\nrug_indices = np.random.choice(len(X), size=min(40, len(X)), replace=False)\nrug_x_values = X[rug_indices, feature_idx]\ny_min = float(np.min(pd_values) - 0.15 * (np.max(pd_values) - np.min(pd_values)))\nrug_points = [(float(x), y_min) for x in sorted(rug_x_values)]\nchart.add(\"Training Data (rug)\", rug_points, stroke=False, dots_size=5)\n\n# Save as PNG and HTML\nchart.render_to_png(f\"plot-{THEME}.png\")\nwith open(f\"plot-{THEME}.html\", \"wb\") as f:\n    f.write(chart.render())\n"}