{"spec_id":"shap-summary","library":"plotnine","language":"python","code":"\"\"\" anyplot.ai\nshap-summary: SHAP Summary Plot\nLibrary: plotnine 0.15.4 | Python 3.13.13\nQuality: 96/100 | Created: 2026-05-14\n\"\"\"\n\nimport os\nimport site\nimport sys\n\n\n# Add site-packages to the beginning of path to prioritize installed packages\nsite_packages = next((p for p in site.getsitepackages() if \"site-packages\" in p), None)\nif site_packages:\n    sys.path.insert(0, site_packages)\n\nimport numpy as np\nimport pandas as pd\nfrom plotnine import (\n    aes,\n    element_line,\n    element_rect,\n    element_text,\n    geom_point,\n    geom_vline,\n    ggplot,\n    ggsave,\n    labs,\n    scale_color_cmap,\n    theme,\n    theme_minimal,\n)\n\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# Generate synthetic SHAP-like data\nnp.random.seed(42)\nn_samples = 250\nn_features = 15\n\n# Feature names (simulating model features)\nfeature_names = [\n    \"Radius\",\n    \"Texture\",\n    \"Perimeter\",\n    \"Area\",\n    \"Smoothness\",\n    \"Compactness\",\n    \"Concavity\",\n    \"Concave Points\",\n    \"Symmetry\",\n    \"Fractal Dimension\",\n    \"Gray Mean\",\n    \"Gray Std\",\n    \"Radius SE\",\n    \"Texture SE\",\n    \"Perimeter SE\",\n]\n\n# Generate realistic SHAP values with different distributions per feature\nshap_values = np.zeros((n_samples, n_features))\nfeature_values = np.zeros((n_samples, n_features))\n\nfor i in range(n_features):\n    # Different distributions for different features\n    scale = np.random.uniform(0.3, 1.5)\n    center = np.random.uniform(-0.5, 0.5)\n\n    # Generate SHAP values with some features showing positive/negative effects\n    shap_values[:, i] = np.random.normal(center, scale, n_samples)\n\n    # Generate normalized feature values (0 to 1) for coloring\n    feature_values[:, i] = np.random.uniform(0, 1, n_samples)\n\n# Calculate importance (mean absolute SHAP value) and sort\nfeature_importance = np.abs(shap_values).mean(axis=0)\nsorted_indices = np.argsort(feature_importance)[::-1]\n\n# Create long format dataframe for plotnine\nrows = []\nfor rank, feat_idx in enumerate(sorted_indices):\n    feat_name = feature_names[feat_idx]\n    shap_vals = shap_values[:, feat_idx]\n    feat_vals = feature_values[:, feat_idx]\n\n    for shap_val, feat_val in zip(shap_vals, feat_vals, strict=False):\n        rows.append({\"feature\": feat_name, \"shap_value\": shap_val, \"feature_value\": feat_val, \"feature_rank\": rank})\n\ndf = pd.DataFrame(rows)\n\n# Create categorical feature order for Y-axis (sorted by importance)\nsorted_feature_names = [feature_names[i] for i in sorted_indices]\ndf[\"feature\"] = pd.Categorical(df[\"feature\"], categories=sorted_feature_names, ordered=True)\n\n# Plot\nplot = (\n    ggplot(df, aes(x=\"shap_value\", y=\"feature\", color=\"feature_value\"))\n    + geom_point(size=2.5, alpha=0.6)\n    + geom_vline(xintercept=0, linetype=\"solid\", color=INK_SOFT, size=0.8, alpha=0.5)\n    + scale_color_cmap(cmap_name=\"BrBG\", limits=[0, 1])\n    + labs(\n        title=\"shap-summary · plotnine · anyplot.ai\",\n        x=\"SHAP Value (impact on prediction)\",\n        y=\"Feature\",\n        color=\"Feature Value\\n(low → high)\",\n    )\n    + theme_minimal()\n    + theme(\n        figure_size=(16, 9),\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.3, alpha=0.10),\n        panel_grid_minor=element_line(color=INK, size=0.2, alpha=0.05),\n        panel_border=element_rect(color=INK_SOFT, fill=None),\n        plot_title=element_text(size=24, color=INK, weight=\"medium\"),\n        axis_title=element_text(size=20, color=INK),\n        axis_text=element_text(size=16, color=INK_SOFT),\n        axis_line=element_line(color=INK_SOFT, size=0.5),\n        legend_background=element_rect(fill=ELEVATED_BG, color=INK_SOFT),\n        legend_text=element_text(size=16, color=INK_SOFT),\n        legend_title=element_text(size=16, color=INK),\n    )\n)\n\n# Save to script directory\nscript_dir = os.path.dirname(os.path.abspath(__file__))\nggsave(plot, filename=os.path.join(script_dir, f\"plot-{THEME}.png\"), dpi=300, width=16, height=9)\n"}