{"spec_id":"logistic-regression","library":"makie","language":"julia","code":"# anyplot.ai\n# logistic-regression: Logistic Regression Curve Plot\n# Library: makie 0.21.9 | Julia 1.11.9\n# Quality: 92/100 | Created: 2026-09-02\n\nusing CairoMakie\nusing Colors\nusing LinearAlgebra\nusing Random\nusing Statistics\n\nRandom.seed!(42)\n\n# --- Theme tokens ------------------------------------------------------------\nTHEME     = get(ENV, \"ANYPLOT_THEME\", \"light\")\nPAGE_BG   = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nINK       = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nINK_SOFT  = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\n\n# Imprint palette — semantic exception: outcome maps to health status (good/bad)\nHEALTHY_COLOR  = colorant\"#009E73\"  # class 0, no diabetes — brand green, always-first series\nDIABETIC_COLOR = colorant\"#AE3030\"  # class 1, diabetes — semantic anchor for the adverse outcome\nCURVE_COLOR    = INK                # fitted probability curve — neutral reference line\nTHRESHOLD_COLOR = colorant\"#DDCC77\" # decision threshold — amber warning anchor\n\n# --- Data: fasting glucose vs. diabetes diagnosis -----------------------------\nn = 220\nglucose = clamp.(120.0 .+ 28.0 .* randn(n), 65.0, 210.0)        # fasting glucose, mg/dL\nglucose_mean = mean(glucose)\nglucose_std = std(glucose)\nglucose_z = (glucose .- glucose_mean) ./ glucose_std\n\ntrue_intercept = -0.3\ntrue_slope = 1.6\ntrue_prob = 1.0 ./ (1.0 .+ exp.(-(true_intercept .+ true_slope .* glucose_z)))\ndiagnosis = Float64.(rand(n) .< true_prob)                     # 0 = no diabetes, 1 = diabetes\n\n# --- Fit logistic regression via Newton-Raphson (IRLS) ------------------------\ndesign = hcat(ones(n), glucose_z)\nbeta = zeros(2)\nweights = ones(n)\nfor _ in 1:25\n    eta = design * beta\n    mu = 1.0 ./ (1.0 .+ exp.(-eta))\n    global weights = max.(mu .* (1.0 .- mu), 1e-8)\n    hessian = design' * (design .* weights)\n    gradient = design' * (diagnosis .- mu)\n    global beta = beta + hessian \\ gradient\nend\ncovariance = inv(design' * (design .* weights))\n\n# --- Fitted curve + 95% confidence band on a smooth glucose grid --------------\ngrid_n = 200\nglucose_grid = collect(range(minimum(glucose), maximum(glucose), length=grid_n))\ngrid_z = (glucose_grid .- glucose_mean) ./ glucose_std\ndesign_grid = hcat(ones(grid_n), grid_z)\n\neta_grid = design_grid * beta\nprob_grid = 1.0 ./ (1.0 .+ exp.(-eta_grid))\nse_eta = [sqrt(design_grid[i, :]' * covariance * design_grid[i, :]) for i in 1:grid_n]\nprob_lower = 1.0 ./ (1.0 .+ exp.(-(eta_grid .- 1.96 .* se_eta)))\nprob_upper = 1.0 ./ (1.0 .+ exp.(-(eta_grid .+ 1.96 .* se_eta)))\n\n# Jitter the binary outcomes slightly so overlapping points stay visible\ny_jitter = diagnosis .+ (rand(n) .- 0.5) .* 0.08\nhealthy_mask = diagnosis .== 0.0\n\n# --- Plot ----------------------------------------------------------------------\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title             = \"logistic-regression · julia · makie · anyplot.ai\",\n    titlesize         = 20,\n    titlecolor        = INK,\n    xlabel            = \"Fasting Glucose (mg/dL)\",\n    ylabel            = \"Probability of Diabetes\",\n    xlabelsize        = 16,\n    ylabelsize        = 16,\n    xlabelcolor       = INK,\n    ylabelcolor       = INK,\n    xticklabelsize    = 13,\n    yticklabelsize    = 13,\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.12),\n    ygridcolor        = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    xminorgridvisible = false,\n    yminorgridvisible = false,\n)\nylims!(ax, -0.08, 1.08)\n\nband!(ax, glucose_grid, prob_lower, prob_upper; color = (CURVE_COLOR, 0.15), label = \"95% confidence band\")\nhlines!(ax, [0.5]; color = THRESHOLD_COLOR, linewidth = 2.5, linestyle = :dash, label = \"Decision threshold (p = 0.5)\")\nlines!(ax, glucose_grid, prob_grid; color = CURVE_COLOR, linewidth = 3, label = \"Fitted probability\")\nscatter!(ax, glucose[healthy_mask], y_jitter[healthy_mask];\n         color = HEALTHY_COLOR, markersize = 11, alpha = 0.6, strokewidth = 0, label = \"No diabetes\")\nscatter!(ax, glucose[.!healthy_mask], y_jitter[.!healthy_mask];\n         color = DIABETIC_COLOR, markersize = 11, alpha = 0.6, strokewidth = 0, label = \"Diabetes\")\n\naxislegend(ax; position = :rb, backgroundcolor = ELEVATED_BG, framevisible = false, labelcolor = INK_SOFT, labelsize = 13)\n\n# --- Save ----------------------------------------------------------------------\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}