{"spec_id":"qq-basic","library":"matplotlib","language":"python","code":"\"\"\" anyplot.ai\nqq-basic: Basic Q-Q Plot\nLibrary: matplotlib 3.11.1 | Python 3.13.14\nQuality: 92/100 | Updated: 2026-07-24\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nfrom scipy import stats\n\n\n# Theme tokens\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\"  # Imprint palette position 1 — scatter points\nREF_COLOR = \"#C475FD\"  # Imprint palette position 2 — reference line\n\n# Data: systolic blood pressure (mmHg) from a mixed patient cohort\n# Bimodal mixture of normotensive (n=75) and hypertensive (n=25) patients\nnp.random.seed(42)\nnormotensive = np.random.normal(loc=120, scale=10, size=75)\nhypertensive = np.random.normal(loc=155, scale=15, size=25)\nbp_readings = np.concatenate([normotensive, hypertensive])\n\n# Standardize for comparison with the N(0,1) reference distribution\nbp_std = (bp_readings - bp_readings.mean()) / bp_readings.std(ddof=1)\n\n# Compute Q-Q quantiles via scipy.stats.probplot (idiomatic ecosystem approach)\n(theoretical_q, sample_q), _ = stats.probplot(bp_std, dist=\"norm\")\ntheoretical_q = np.array(theoretical_q)\nsample_q = np.array(sample_q)\n\n# 95% pointwise confidence band: where sample quantiles should fall if data were normal\nn = len(bp_std)\nprobs = (np.arange(1, n + 1) - 0.5) / n\nphi_z = stats.norm.pdf(theoretical_q)\nse = np.sqrt(probs * (1 - probs)) / (np.sqrt(n) * phi_z)\nci_low = theoretical_q - 1.96 * se\nci_high = theoretical_q + 1.96 * se\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400, facecolor=PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# 95% confidence band — points outside reveal non-normality\nax.fill_between(theoretical_q, ci_low, ci_high, color=BRAND, alpha=0.22, label=\"95% CI band\", zorder=1)\n\n# Sample quantile scatter — smaller markers keep the dense central cluster separable\nax.scatter(theoretical_q, sample_q, s=70, alpha=0.75, color=BRAND, edgecolors=PAGE_BG, linewidths=0.8, zorder=3)\n\n# Reference line y = x\nref_lo = min(theoretical_q.min(), sample_q.min())\nref_hi = max(theoretical_q.max(), sample_q.max())\nax.plot(\n    [ref_lo, ref_hi],\n    [ref_lo, ref_hi],\n    color=REF_COLOR,\n    linewidth=2.5,\n    linestyle=\"--\",\n    label=\"Reference line (y = x)\",\n    zorder=2,\n)\n\n# Annotate the upper-tail deviation caused by the hypertensive cohort\nupper_mask = theoretical_q > 1.0\ndev_idx = np.argmax(np.abs(sample_q[upper_mask] - theoretical_q[upper_mask]))\nann_x, ann_y = theoretical_q[upper_mask][dev_idx], sample_q[upper_mask][dev_idx]\nax.annotate(\n    \"Hypertensive cohort\\ndeviates from normal\",\n    xy=(ann_x, ann_y),\n    xytext=(-0.55, 2.5),\n    fontsize=7.5,\n    color=INK_SOFT,\n    ha=\"center\",\n    arrowprops={\"arrowstyle\": \"->\", \"color\": INK_SOFT, \"linewidth\": 0.8},\n    zorder=4,\n)\n\n# Style\nax.set_xlabel(\"Theoretical Quantiles\", fontsize=10, color=INK)\nax.set_ylabel(\"Sample Quantiles\", fontsize=10, color=INK)\nax.set_title(\"qq-basic · python · matplotlib · anyplot.ai\", fontsize=12, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\nax.spines[\"top\"].set_visible(False)\nax.spines[\"right\"].set_visible(False)\nfor spine in (\"left\", \"bottom\"):\n    ax.spines[spine].set_color(INK_SOFT)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.8, color=INK)\nax.xaxis.grid(True, alpha=0.06, linewidth=0.8, color=INK)\n\nleg = ax.legend(fontsize=8, loc=\"lower right\")\nleg.get_frame().set_facecolor(ELEVATED_BG)\nleg.get_frame().set_edgecolor(INK_SOFT)\nplt.setp(leg.get_texts(), color=INK_SOFT)\n\n# Save\nplt.tight_layout()\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}