{"spec_id":"line-growth-percentile","library":"makie","language":"julia","code":"# anyplot.ai\n# line-growth-percentile: Pediatric Growth Chart with Percentile Curves\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 89/100 | Created: 2026-06-20\n\nusing CairoMakie\nusing Colors\n\n# Theme tokens\nconst THEME       = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG     = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst ELEVATED_BG = THEME == \"light\" ? colorant\"#FFFDF6\" : colorant\"#242420\"\nconst INK         = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT    = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\n\n# Imprint palette — first series always #009E73\nconst IMPRINT_PALETTE = [\n    colorant\"#009E73\",  # 1 brand green\n    colorant\"#C475FD\",  # 2 lavender\n    colorant\"#4467A3\",  # 3 blue\n    colorant\"#BD8233\",  # 4 ochre\n    colorant\"#AE3030\",  # 5 matte red\n    colorant\"#2ABCCD\",  # 6 cyan\n    colorant\"#954477\",  # 7 rose\n    colorant\"#99B314\",  # 8 lime\n]\n\n# Boys chart: Imprint blue for bands (semantic sky/water → blue)\nconst BAND_COLOR    = colorant\"#4467A3\"  # Imprint position 3\nconst PATIENT_COLOR = colorant\"#009E73\"  # Imprint position 1 — brand green, contrasting\n\n# --- Data ---\n# Approximate WHO weight-for-age reference for boys (0–36 months)\nages = collect(Float64, 0:36)\n\n# P50 median weight (kg)\np50 = [\n     3.3,  4.5,  5.6,  6.4,  7.0,  7.5,  7.9,  8.3,  8.6,  8.9,\n     9.2,  9.4,  9.6,  9.9, 10.1, 10.4, 10.6, 10.8, 11.1, 11.3,\n    11.5, 11.7, 11.9, 12.1, 12.3, 12.4, 12.6, 12.8, 13.0, 13.1,\n    13.3, 13.5, 13.6, 13.8, 13.9, 14.1, 14.3,\n]\n\n# SD (kg) — grows with age\nsd = [\n    0.40, 0.52, 0.63, 0.70, 0.75, 0.79, 0.82, 0.86, 0.89, 0.92,\n    0.94, 0.96, 0.98, 1.01, 1.03, 1.05, 1.07, 1.09, 1.11, 1.13,\n    1.15, 1.17, 1.19, 1.21, 1.23, 1.25, 1.27, 1.29, 1.31, 1.33,\n    1.35, 1.37, 1.39, 1.41, 1.43, 1.45, 1.47,\n]\n\n# Percentile curves via z-score offsets\np3  = p50 .- 1.88 .* sd\np10 = p50 .- 1.28 .* sd\np25 = p50 .- 0.67 .* sd\np75 = p50 .+ 0.67 .* sd\np90 = p50 .+ 1.28 .* sd\np97 = p50 .+ 1.88 .* sd\n\n# Individual patient: boy tracking near 65th percentile across well-child visits\npatient_ages   = Float64[0, 2, 4, 6, 9, 12, 15, 18, 21, 24, 30, 36]\npatient_weight = [3.5, 5.9, 7.3, 8.3, 9.6, 10.2, 11.0, 11.8, 12.2, 12.9, 13.9, 15.0]\n\n# --- Plot ---\ntitle_str = \"line-growth-percentile · julia · makie · anyplot.ai\"\n\nfig = Figure(\n    size            = (1600, 900),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title              = title_str,\n    titlesize          = 20,\n    titlecolor         = INK,\n    subtitle           = \"Boys weight-for-age — WHO reference (0–36 months)\",\n    subtitlecolor      = INK_SOFT,\n    subtitlesize       = 13,\n    xlabel             = \"Age (months)\",\n    ylabel             = \"Weight (kg)\",\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    xgridvisible       = false,\n    ygridvisible       = true,\n    ygridcolor         = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    xticks             = 0:6:36,\n    yticks             = 2:2:20,\n)\n\n# Extend x-axis right to leave room for percentile labels\nxlims!(ax, -0.5, 42.0)\nylims!(ax, 1.5, 20.0)\n\n# Percentile bands — graduated: outer bands darker, inner bands lighter\nband!(ax, ages, p3,  p10; color = (BAND_COLOR, 0.38))\nband!(ax, ages, p10, p25; color = (BAND_COLOR, 0.23))\nband!(ax, ages, p25, p50; color = (BAND_COLOR, 0.16))\nband!(ax, ages, p50, p75; color = (BAND_COLOR, 0.16))\nband!(ax, ages, p75, p90; color = (BAND_COLOR, 0.23))\nband!(ax, ages, p90, p97; color = (BAND_COLOR, 0.38))\n\n# Non-median percentile curves (thin)\nfor (crv, alpha) in [\n    (p3, 0.50), (p10, 0.40), (p25, 0.35),\n    (p75, 0.35), (p90, 0.40), (p97, 0.50),\n]\n    lines!(ax, ages, crv; color = (BAND_COLOR, alpha), linewidth = 1.2)\nend\n\n# Median (P50) — emphasized and labeled in legend\nlines!(ax, ages, p50; color = BAND_COLOR, linewidth = 2.5, label = \"WHO P50 median\")\n\n# Patient data — connected scatter\nscatterlines!(\n    ax, patient_ages, patient_weight;\n    color      = PATIENT_COLOR,\n    linewidth  = 2.5,\n    markersize = 12,\n    label      = \"Patient (boy, age 0–36 mo)\",\n)\n\n# Percentile labels on right margin\nlabel_x = 37.5\nfor (lbl, yv) in [\n    (\"P3\",  p3[end]),  (\"P10\", p10[end]), (\"P25\", p25[end]),\n    (\"P50\", p50[end]), (\"P75\", p75[end]), (\"P90\", p90[end]), (\"P97\", p97[end]),\n]\n    lbl_color = lbl == \"P50\" ? INK : INK_SOFT\n    lbl_size  = lbl == \"P50\" ? 14  : 13\n    text!(ax, label_x, yv;\n          text     = lbl,\n          color    = lbl_color,\n          fontsize = lbl_size,\n          align    = (:left, :center),\n    )\nend\n\n# Legend\naxislegend(ax;\n    position        = :lt,\n    backgroundcolor = ELEVATED_BG,\n    framecolor      = INK_SOFT,\n    labelcolor      = INK,\n    labelsize       = 13,\n    framevisible    = false,\n)\n\n# --- Save ---\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}