{"spec_id":"elbow-curve","library":"makie","language":"julia","code":"# anyplot.ai\n# elbow-curve: Elbow Curve for K-Means Clustering\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 83/100 | Created: 2026-09-05\n\nusing CairoMakie\nusing Colors\nusing Random\n\nRandom.seed!(42)\n\n# --- Theme tokens -----------------------------------------------------------\nconst THEME    = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG  = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst INK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\", colorant\"#C475FD\", colorant\"#4467A3\", colorant\"#BD8233\",\n    colorant\"#AE3030\", colorant\"#2ABCCD\", colorant\"#954477\", colorant\"#99B314\",\n]\n\n# --- Data ---------------------------------------------------------------\n# Simulated K-means inertia for customer segmentation on behavioral features.\n# Inertia falls sharply until the natural cluster count, then flattens.\nk_values = collect(1:10)\ntrue_k = 4\nbase_inertia = 5200.0\ndecay = [1.0, 0.42, 0.24, 0.15, 0.115, 0.095, 0.081, 0.070, 0.062, 0.056]\nnoise = randn(length(k_values)) .* 25.0\ninertia = base_inertia .* decay .+ noise\ninertia = round.(inertia, digits = 1)\nelbow_idx = true_k\n\n# --- Plot -----------------------------------------------------------------\nfig = Figure(\n    resolution      = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = \"elbow-curve · julia · makie · anyplot.ai\",\n    titlesize          = 20,\n    titlecolor         = INK,\n    xlabel             = \"Number of Clusters (k)\",\n    ylabel             = \"Inertia (Within-Cluster Sum of Squares)\",\n    xlabelsize         = 14,\n    ylabelsize         = 14,\n    xlabelcolor        = INK,\n    ylabelcolor        = INK,\n    xticklabelsize     = 12,\n    yticklabelsize     = 12,\n    xticklabelcolor    = INK_SOFT,\n    yticklabelcolor    = INK_SOFT,\n    xtickcolor         = INK_SOFT,\n    ytickcolor         = INK_SOFT,\n    backgroundcolor    = PAGE_BG,\n    topspinevisible    = false,\n    rightspinevisible  = false,\n    leftspinecolor     = INK_SOFT,\n    bottomspinecolor   = INK_SOFT,\n    xgridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.15),\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.15),\n    xminorgridvisible  = false,\n    yminorgridvisible  = false,\n    xticks             = k_values,\n)\n\nlines!(ax, k_values, inertia; color = IMPRINT_PALETTE[1], linewidth = 3.0)\nscatter!(ax, k_values, inertia; color = IMPRINT_PALETTE[1], markersize = 16, strokewidth = 1.5, strokecolor = PAGE_BG)\n\n# Highlight the elbow point with an outlined marker in the same brand color.\nscatter!(\n    ax, [k_values[elbow_idx]], [inertia[elbow_idx]];\n    color = PAGE_BG, markersize = 22, strokewidth = 3, strokecolor = IMPRINT_PALETTE[1],\n)\naccent = IMPRINT_PALETTE[3]  # secondary Imprint accent (blue) for the guide line\nvlines!(ax, [k_values[elbow_idx]]; color = RGBAf(accent.r, accent.g, accent.b, 0.55), linewidth = 1.5, linestyle = :dash)\n\n# Label the elbow directly on the chart with a Makie text! annotation.\ntext!(\n    ax, k_values[elbow_idx], inertia[elbow_idx];\n    text      = \"k=4 (optimal)\",\n    align     = (:left, :bottom),\n    offset    = (12, 12),\n    fontsize  = 14,\n    color     = accent,\n    font      = :bold,\n)\n\n# --- Save -------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}