{"spec_id":"line-growth-percentile","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nline-growth-percentile: Pediatric Growth Chart with Percentile Curves\nLibrary: matplotlib 3.11.0 | Python 3.13.14\nQuality: 89/100 | Updated: 2026-06-20\n\"\"\"\n\nimport os\nimport sys\n\n\n# Remove the script's own directory from sys.path so \"import matplotlib\" finds\n# the installed package rather than this file (which shares its name).\nif sys.path and sys.path[0] != \"\":\n    sys.path.pop(0)\n\nimport matplotlib.pyplot as plt\nimport matplotlib.ticker as ticker\nimport numpy as np\n\n\n# Theme-adaptive chrome — Imprint palette design system\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\"\nINK_MUTED = \"#6B6A63\" if THEME == \"light\" else \"#A8A79F\"\n\n# Imprint palette — 8 hues, theme-independent, hybrid-v3 sort\nIMPRINT_PALETTE = [\"#009E73\", \"#C475FD\", \"#4467A3\", \"#BD8233\", \"#AE3030\", \"#2ABCCD\", \"#954477\", \"#99B314\"]\nBLUE = IMPRINT_PALETTE[2]  # #4467A3 — Imprint blue, position 3; boys-blue semantic exception\n\n# --- Data ---\n# Synthetic WHO-like weight-for-age reference for boys 0–36 months\nage_months = np.arange(0, 37, 1)\nmedian_weight = 3.3 + 0.7 * age_months - 0.009 * age_months**2 + 0.00007 * age_months**3\nsd = 0.35 + 0.025 * age_months\n\nz_scores = {\"P3\": -1.881, \"P10\": -1.282, \"P25\": -0.674, \"P50\": 0.0, \"P75\": 0.674, \"P90\": 1.282, \"P97\": 1.881}\npercentiles = {label: median_weight + z * sd for label, z in z_scores.items()}\n\n# Patient: large-for-gestational-age (LGA) boy normalizing toward the median.\n# z-score trajectory: z=1.0 at birth (≈P84) → z=0.0 at 36 months (P50).\n# Computed via: patient = median(t) + z(t) * sd(t), z(t) = 1 – t/36.\npatient_ages = np.array([0, 1, 2, 4, 6, 9, 12, 15, 18, 24, 30, 36])\npatient_weights = np.array([3.7, 4.4, 5.0, 6.4, 7.6, 9.4, 11.0, 12.4, 13.8, 16.2, 18.3, 20.1])\n\n# --- Canvas: landscape 3200×1800 px — prompts/library/matplotlib.md \"Canvas\" ---\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# --- Developmental phase shading (axvspan — distinctive matplotlib feature) ---\nax.axvspan(0, 12, color=INK, alpha=0.04, linewidth=0, zorder=0)\nax.text(\n    6,\n    0.025,\n    \"Infancy\",\n    transform=ax.get_xaxis_transform(),\n    fontsize=7,\n    color=INK_MUTED,\n    ha=\"center\",\n    va=\"bottom\",\n    style=\"italic\",\n)\n\n# --- Percentile bands: Imprint #4467A3 at varied alpha (boys-blue semantic exception) ---\nband_pairs = [(\"P3\", \"P10\"), (\"P10\", \"P25\"), (\"P25\", \"P75\"), (\"P75\", \"P90\"), (\"P90\", \"P97\")]\nband_alphas = [0.30, 0.20, 0.12, 0.20, 0.30]\n\nfor (lower, upper), alpha in zip(band_pairs, band_alphas, strict=True):\n    ax.fill_between(age_months, percentiles[lower], percentiles[upper], color=BLUE, alpha=alpha, linewidth=0)\n\n# --- Percentile curves ---\npercentile_labels = [\"P3\", \"P10\", \"P25\", \"P50\", \"P75\", \"P90\", \"P97\"]\nline_widths = [0.7, 0.7, 1.0, 2.5, 1.0, 0.7, 0.7]\nline_styles = [\"--\", \"--\", \"-\", \"-\", \"-\", \"--\", \"--\"]\ncurve_alphas = [0.55, 0.65, 0.80, 1.0, 0.80, 0.65, 0.55]\n\nfor label, lw, ls, alpha in zip(percentile_labels, line_widths, line_styles, curve_alphas, strict=True):\n    ax.plot(age_months, percentiles[label], linewidth=lw, linestyle=ls, color=BLUE, alpha=alpha)\n\n# --- Percentile labels on right margin with collision avoidance ---\n# Prevents compression when adjacent percentile curves are close at the chart edge.\npct_y_true = {label: float(percentiles[label][-1]) for label in percentile_labels}\nsorted_pct = sorted(percentile_labels, key=lambda lbl: pct_y_true[lbl])\n\nMIN_SEP = 1.0  # minimum kg between adjacent labels (≈ label height at fontsize=8)\npct_y_adj: dict[str, float] = {}\nprev_label = None\nfor label in sorted_pct:\n    y = pct_y_true[label]\n    if prev_label is not None and pct_y_adj[prev_label] + MIN_SEP > y:\n        y = pct_y_adj[prev_label] + MIN_SEP\n    pct_y_adj[label] = y\n    prev_label = label\n\nfor label in percentile_labels:\n    fw = \"bold\" if label == \"P50\" else \"normal\"\n    fs = 9 if label == \"P50\" else 8\n    ax.annotate(\n        label,\n        xy=(36, pct_y_true[label]),\n        xytext=(36.6, pct_y_adj[label]),\n        fontsize=fs,\n        fontweight=fw,\n        color=BLUE,\n        va=\"center\",\n        ha=\"left\",\n        annotation_clip=False,\n    )\n\n# --- Patient trajectory: LGA normalization ---\nax.plot(\n    patient_ages,\n    patient_weights,\n    marker=\"o\",\n    markersize=5.5,\n    linewidth=2.0,\n    color=IMPRINT_PALETTE[0],  # Imprint green — first categorical series\n    markerfacecolor=IMPRINT_PALETTE[0],\n    markeredgecolor=PAGE_BG,\n    markeredgewidth=1.0,\n    zorder=5,\n    label=\"Patient (Boy, LGA)\",\n)\n\n# --- Clinical annotations — both in INK_SOFT, avoiding red-green CVD pairing ---\nax.annotate(\n    \"High birth weight (LGA)\",\n    xy=(0, patient_weights[0]),\n    xytext=(3.0, patient_weights[0] + 1.5),\n    fontsize=8,\n    color=INK_SOFT,\n    arrowprops={\"arrowstyle\": \"-|>\", \"color\": INK_SOFT, \"lw\": 1.0, \"connectionstyle\": \"arc3,rad=0.25\"},\n    va=\"bottom\",\n    ha=\"left\",\n    zorder=6,\n)\n\nax.annotate(\n    \"Normalized to P50\",\n    xy=(36, patient_weights[-1]),\n    xytext=(26, patient_weights[-1] - 4.0),\n    fontsize=8,\n    color=INK_SOFT,\n    arrowprops={\"arrowstyle\": \"-|>\", \"color\": INK_SOFT, \"lw\": 1.0, \"connectionstyle\": \"arc3,rad=-0.25\"},\n    va=\"top\",\n    ha=\"left\",\n    zorder=6,\n)\n\n# --- Chrome ---\ntitle = \"line-growth-percentile · python · matplotlib · anyplot.ai\"\ntitle_fontsize = max(8, round(12 * 67 / len(title))) if len(title) > 67 else 12\nfig.suptitle(title, fontsize=title_fontsize, fontweight=\"medium\", color=INK, y=0.98)\n\nax.set_title(\"Weight-for-Age, Boys, 0–36 months  •  WHO Growth Standards\", fontsize=8, color=INK_MUTED, pad=5)\n\nax.set_xlabel(\"Age (months)\", fontsize=10, color=INK)\nax.set_ylabel(\"Weight (kg)\", fontsize=10, color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT, labelcolor=INK_SOFT)\n\nax.set_xlim(-0.5, 36)\nax.set_xticks(np.arange(0, 37, 3))\nax.xaxis.set_minor_locator(ticker.MultipleLocator(1))\nax.tick_params(axis=\"x\", which=\"minor\", length=2, width=0.4, colors=INK_SOFT)\n\ny_max = float(percentiles[\"P97\"][-1]) + 2.5\nax.set_ylim(0, y_max)\n\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nax.spines[\"left\"].set_color(INK_SOFT)\nax.spines[\"left\"].set_linewidth(0.6)\nax.spines[\"bottom\"].set_color(INK_SOFT)\nax.spines[\"bottom\"].set_linewidth(0.6)\n\nax.yaxis.grid(True, alpha=0.15, linewidth=0.6, color=INK)\nax.set_axisbelow(True)\n\nleg = ax.legend(fontsize=8, loc=\"upper left\", framealpha=0.9)\nif leg:\n    leg.get_frame().set_facecolor(ELEVATED_BG)\n    leg.get_frame().set_edgecolor(INK_SOFT)\n    plt.setp(leg.get_texts(), color=INK_SOFT)\n\n# Right margin reserves space for percentile labels; top for two title lines\nfig.subplots_adjust(left=0.09, right=0.89, top=0.82, bottom=0.13)\n\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}