{"spec_id":"silhouette-basic","library":"plotly","language":"python","code":"\"\"\" anyplot.ai\nsilhouette-basic: Silhouette Plot\nLibrary: plotly 6.7.0 | Python 3.13.13\nQuality: 77/100 | Updated: 2026-05-10\n\"\"\"\n\nimport numpy as np\nimport plotly.graph_objects as go\nfrom sklearn.cluster import KMeans\nfrom sklearn.datasets import load_iris\nfrom sklearn.metrics import silhouette_samples, silhouette_score\n\n\n# Data - load iris dataset and perform clustering\nnp.random.seed(42)\niris = load_iris()\nX = iris.data\nn_clusters = 3\n\n# Perform K-means clustering\nkmeans = KMeans(n_clusters=n_clusters, random_state=42, n_init=10)\ncluster_labels = kmeans.fit_predict(X)\n\n# Compute silhouette scores\nsilhouette_vals = silhouette_samples(X, cluster_labels)\nsilhouette_avg = silhouette_score(X, cluster_labels)\n\n# Colors for clusters (Python blue, Python yellow, and a colorblind-safe third color)\ncolors = [\"#306998\", \"#FFD43B\", \"#E84A5F\"]\n\n# Create figure\nfig = go.Figure()\n\ny_lower = 10\ncluster_info = []\n\nfor i in range(n_clusters):\n    # Get silhouette values for this cluster\n    cluster_silhouette_vals = silhouette_vals[cluster_labels == i]\n    cluster_silhouette_vals.sort()\n\n    cluster_size = cluster_silhouette_vals.shape[0]\n    y_upper = y_lower + cluster_size\n    cluster_avg = np.mean(cluster_silhouette_vals)\n\n    # Create y positions for bars\n    y_positions = np.arange(y_lower, y_upper)\n\n    # Add horizontal bars for each sample\n    fig.add_trace(\n        go.Bar(\n            x=cluster_silhouette_vals,\n            y=y_positions,\n            orientation=\"h\",\n            marker=dict(color=colors[i], line=dict(width=0)),\n            name=f\"Cluster {i} (avg: {cluster_avg:.2f})\",\n            hovertemplate=f\"Cluster {i}<br>Silhouette: %{{x:.3f}}<extra></extra>\",\n        )\n    )\n\n    # Store cluster info for annotation\n    cluster_info.append({\"y_center\": y_lower + 0.5 * cluster_size, \"avg\": cluster_avg, \"cluster\": i})\n\n    y_lower = y_upper + 10  # Gap between clusters\n\n# Add vertical line for average silhouette score\nfig.add_vline(\n    x=silhouette_avg,\n    line=dict(color=\"red\", width=3, dash=\"dash\"),\n    annotation_text=f\"Average: {silhouette_avg:.3f}\",\n    annotation_position=\"top\",\n    annotation_font=dict(size=20, color=\"red\"),\n)\n\n# Add vertical line at 0\nfig.add_vline(x=0, line=dict(color=\"gray\", width=2))\n\n# Update layout\nfig.update_layout(\n    title=dict(text=\"silhouette-basic \\u00b7 plotly \\u00b7 pyplots.ai\", font=dict(size=32), x=0.5, xanchor=\"center\"),\n    xaxis=dict(\n        title=dict(text=\"Silhouette Coefficient\", font=dict(size=24)),\n        tickfont=dict(size=18),\n        range=[-0.2, 1.0],\n        showgrid=True,\n        gridcolor=\"rgba(0,0,0,0.1)\",\n        zeroline=True,\n        zerolinecolor=\"gray\",\n        zerolinewidth=2,\n    ),\n    yaxis=dict(\n        title=dict(text=\"Samples (grouped by cluster)\", font=dict(size=24)),\n        tickfont=dict(size=18),\n        showticklabels=False,\n    ),\n    legend=dict(font=dict(size=20), x=0.98, xanchor=\"right\", y=0.98, yanchor=\"top\"),\n    template=\"plotly_white\",\n    margin=dict(l=100, r=100, t=120, b=100),\n    bargap=0,\n    showlegend=True,\n)\n\n# Add cluster annotations on y-axis\nfor info in cluster_info:\n    fig.add_annotation(\n        x=-0.18,\n        y=info[\"y_center\"],\n        text=f\"Cluster {info['cluster']}\",\n        showarrow=False,\n        font=dict(size=18),\n        xanchor=\"center\",\n    )\n\n# Save as PNG and HTML\nfig.write_image(\"plot.png\", width=1600, height=900, scale=3)\nfig.write_html(\"plot.html\", include_plotlyjs=\"cdn\")\n"}