{"spec_id":"elbow-curve","library":"letsplot","language":"python","code":"\"\"\" anyplot.ai\nelbow-curve: Elbow Curve for K-Means Clustering\nLibrary: letsplot 4.9.0 | Python 3.13.13\nQuality: 91/100 | Updated: 2026-05-10\n\"\"\"\n\nimport os\n\nimport numpy as np\nimport pandas as pd\nfrom lets_plot import *\n\n\nLetsPlot.setup_html()\n\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\"\nBRAND = \"#009E73\"\nACCENT = \"#C475FD\"\n\n# Simulated K-means inertia values showing typical elbow curve pattern\n# Data represents clustering analysis on customer segmentation dataset\nnp.random.seed(42)\n\nk_values = list(range(1, 11))\n\n# Realistic inertia values that show clear elbow at k=4\n# Inertia decreases sharply until k=4, then diminishing returns\ninertias = [\n    12500,  # k=1: all points in one cluster\n    6800,  # k=2: significant drop\n    3900,  # k=3: still improving\n    2100,  # k=4: elbow point (optimal)\n    1800,  # k=5: diminishing returns start\n    1550,  # k=6\n    1380,  # k=7\n    1250,  # k=8\n    1150,  # k=9\n    1080,  # k=10\n]\n\n# Create DataFrame for plotting\ndf = pd.DataFrame({\"k\": k_values, \"Inertia\": inertias})\n\n# Optimal k (elbow point)\noptimal_k = 4\n\n# Create elbow curve plot\nplot = (\n    ggplot(df, aes(x=\"k\", y=\"Inertia\"))\n    + geom_line(size=2, color=BRAND)\n    + geom_point(size=6, color=BRAND, alpha=0.9)\n    + geom_point(data=df[df[\"k\"] == optimal_k], mapping=aes(x=\"k\", y=\"Inertia\"), size=10, color=ACCENT, shape=18)\n    + geom_vline(xintercept=optimal_k, linetype=\"dashed\", color=ACCENT, size=1.5, alpha=0.7)\n    + labs(\n        title=\"elbow-curve · letsplot · anyplot.ai\",\n        x=\"Number of Clusters (k)\",\n        y=\"Inertia (Within-Cluster Sum of Squares)\",\n    )\n    + scale_x_continuous(breaks=k_values)\n    + theme_minimal()\n    + 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.3, linetype=\"solid\"),\n        panel_grid_minor=element_blank(),\n        plot_title=element_text(size=28, face=\"bold\", color=INK),\n        axis_title=element_text(size=22, color=INK),\n        axis_text=element_text(size=18, color=INK_SOFT),\n        axis_line=element_line(color=INK_SOFT, size=0.5),\n    )\n    + ggsize(1600, 900)\n)\n\n# Save as PNG (scale 3x for 4800x2700)\nggsave(plot, f\"plot-{THEME}.png\", path=\".\", scale=3)\n\n# Save interactive HTML\nggsave(plot, f\"plot-{THEME}.html\", path=\".\")\n"}