{"spec_id":"shap-summary","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nshap-summary: SHAP Summary Plot\nLibrary: matplotlib 3.10.9 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-14\n\"\"\"\n\nimport os\nimport sys\nfrom pathlib import Path\n\n\n# Remove the script's directory from path temporarily to avoid import conflicts\nscript_dir = str(Path(__file__).parent)\nif script_dir in sys.path:\n    sys.path.remove(script_dir)\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\n\n# Data - Simulating SHAP values from a house price prediction model\nnp.random.seed(42)\nn_samples = 300\nn_features = 12\n\n# Feature names (house price prediction context)\nfeature_names = [\n    \"Square Footage\",\n    \"Number of Bedrooms\",\n    \"Age of House (years)\",\n    \"Distance to City (km)\",\n    \"Number of Bathrooms\",\n    \"Garage Size\",\n    \"Lot Size (acres)\",\n    \"School Rating\",\n    \"Crime Rate Index\",\n    \"Year Renovated\",\n    \"Property Tax Rate\",\n    \"Median Income (area)\",\n]\n\n# Generate feature values (normalized 0-1 for coloring)\nfeature_values = np.random.rand(n_samples, n_features)\n\n# Generate SHAP values with realistic patterns\n# More important features have larger absolute SHAP values\nimportance_scale = np.array([2.5, 1.8, 1.5, 1.4, 1.2, 1.0, 0.9, 0.8, 0.7, 0.5, 0.4, 0.3])\nshap_values = np.zeros((n_samples, n_features))\n\nfor i in range(n_features):\n    # Create SHAP values with some correlation to feature values\n    # Higher feature values generally -> higher SHAP values (but not always)\n    base_shap = (feature_values[:, i] - 0.5) * importance_scale[i]\n    noise = np.random.randn(n_samples) * importance_scale[i] * 0.3\n    shap_values[:, i] = base_shap + noise\n\n# Sort features by mean absolute SHAP value (most important first)\nmean_abs_shap = np.abs(shap_values).mean(axis=0)\nsorted_indices = np.argsort(mean_abs_shap)[::-1]\n\n# Take top 10 features for clarity\ntop_n = 10\nsorted_indices = sorted_indices[:top_n]\nsorted_feature_names = [feature_names[i] for i in sorted_indices]\nsorted_shap_values = shap_values[:, sorted_indices]\nsorted_feature_values = feature_values[:, sorted_indices]\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# Plot\nfig, ax = plt.subplots(figsize=(16, 9), facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# Use BrBG colormap for diverging data (SHAP values range from negative to positive)\ncmap = plt.cm.BrBG\n\n# Plot each feature as a row of scattered points\nfor i in range(top_n):\n    feature_idx = top_n - 1 - i  # Reverse so most important is at top\n    shap_vals = sorted_shap_values[:, feature_idx]\n    feat_vals = sorted_feature_values[:, feature_idx]\n\n    # Add jitter to y-position to reduce overlap\n    y_positions = np.ones(n_samples) * i + np.random.uniform(-0.15, 0.15, n_samples)\n\n    # Scatter plot with color based on feature value\n    scatter = ax.scatter(\n        shap_vals, y_positions, c=feat_vals, cmap=cmap, s=100, alpha=0.6, edgecolors=\"none\", vmin=0, vmax=1\n    )\n\n# Vertical line at x=0 (theme-adaptive)\nax.axvline(x=0, color=INK_SOFT, linewidth=2.5, linestyle=\"-\", alpha=0.8)\n\n# Styling\nax.set_yticks(range(top_n))\nax.set_yticklabels(sorted_feature_names[::-1], fontsize=16, color=INK_SOFT)\nax.set_xlabel(\"SHAP Value (Impact on Model Output)\", fontsize=20, color=INK)\nax.set_title(\"shap-summary · matplotlib · anyplot.ai\", fontsize=24, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"x\", labelsize=16, colors=INK_SOFT)\n\n# Grid (subtle, vertical only)\nax.grid(True, axis=\"x\", alpha=0.12, linewidth=0.8, color=INK)\nax.set_axisbelow(True)\n\n# Spine styling\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor s in (\"left\", \"bottom\"):\n    ax.spines[s].set_color(INK_SOFT)\n    ax.spines[s].set_linewidth(1.2)\n\n# Colorbar\ncbar = plt.colorbar(scatter, ax=ax, shrink=0.8, aspect=30, pad=0.02)\ncbar.set_label(\"Feature Value\", fontsize=18, color=INK)\ncbar.set_ticks([0, 1])\ncbar.set_ticklabels([\"Low\", \"High\"], fontsize=14, color=INK_SOFT)\ncbar.ax.tick_params(colors=INK_SOFT, labelsize=14)\ncbar.outline.set_edgecolor(INK_SOFT)\ncbar.outline.set_linewidth(1.2)\n\n# Adjust layout\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=300, bbox_inches=\"tight\", facecolor=PAGE_BG)\n"}