{"spec_id":"histogram-capability","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\nhistogram-capability: Process Capability Plot with Specification Limits\nLibrary: seaborn 0.13.2 | Python 3.13.14\nQuality: 90/100 | Updated: 2026-06-20\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\nfrom matplotlib.lines import Line2D\nfrom scipy.stats import norm\n\n\n# Theme tokens — Imprint palette\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\"\n\nBRAND = \"#009E73\"  # Imprint position 1 — histogram bars\nBLUE = \"#4467A3\"  # Imprint position 3 — theoretical normal fit\nCYAN = \"#2ABCCD\"  # Imprint position 6 — empirical KDE\nRED = \"#AE3030\"  # Imprint position 5 — semantic: spec limits / out-of-spec\nAMBER = \"#DDCC77\"  # Imprint semantic anchor — target / caution\n\nsns.set_theme(\n    style=\"ticks\",\n    rc={\n        \"figure.facecolor\": PAGE_BG,\n        \"axes.facecolor\": PAGE_BG,\n        \"axes.edgecolor\": INK_SOFT,\n        \"axes.labelcolor\": INK,\n        \"text.color\": INK,\n        \"xtick.color\": INK_SOFT,\n        \"ytick.color\": INK_SOFT,\n        \"grid.color\": INK,\n        \"grid.alpha\": 0.15,\n        \"legend.facecolor\": ELEVATED_BG,\n        \"legend.edgecolor\": INK_SOFT,\n    },\n)\n\n# Data — pharmaceutical tablet weight QC (target 500 mg, n=200)\nnp.random.seed(42)\nweights = np.random.normal(loc=500.2, scale=2.8, size=200)\nlsl = 490.0\nusl = 510.0\ntarget = 500.0\n\nmean = np.mean(weights)\nsigma = np.std(weights, ddof=1)\ncp = (usl - lsl) / (6 * sigma)\ncpk = min((usl - mean) / (3 * sigma), (mean - lsl) / (3 * sigma))\n\n# Fitted normal distribution curve (scipy — not KDE)\nx_fit = np.linspace(lsl - 4, usl + 4, 400)\ny_fit = norm.pdf(x_fit, mean, sigma)\n\n# Plot\nfig, ax = plt.subplots(figsize=(8, 4.5), dpi=400)\nax.set_facecolor(PAGE_BG)\n\n# Histogram bars\nsns.histplot(weights, bins=25, stat=\"density\", color=BRAND, edgecolor=PAGE_BG, linewidth=0.6, alpha=0.70, ax=ax)\n\n# Fitted normal distribution (parametric — theoretical)\nax.plot(x_fit, y_fit, color=BLUE, linewidth=2.5, zorder=5)\n\n# Empirical KDE (seaborn's non-parametric density estimation)\nsns.kdeplot(weights, color=CYAN, linewidth=2.0, linestyle=\":\", ax=ax, zorder=6)\n\n# Specification limit and target lines\nax.axvline(lsl, color=RED, linestyle=\"--\", linewidth=2.0, zorder=4)\nax.axvline(usl, color=RED, linestyle=\"--\", linewidth=2.0, zorder=4)\nax.axvline(target, color=AMBER, linestyle=\"-.\", linewidth=2.0, zorder=4)\n\n# Shaded capability zones\nxlim = ax.get_xlim()\nax.axvspan(lsl, usl, alpha=0.05, color=BRAND, zorder=0)\nax.axvspan(xlim[0], lsl, alpha=0.07, color=RED, zorder=0)\nax.axvspan(usl, xlim[1], alpha=0.07, color=RED, zorder=0)\n\n# Capability status color and label\nstatus = \"Capable\" if cpk >= 1.33 else \"Adequate\" if cpk >= 1.0 else \"Not Capable\"\ncp_color = BRAND if cpk >= 1.33 else AMBER if cpk >= 1.0 else RED\n\n# Metrics annotation box — status integrated as 5th line\nannotation_text = (\n    f\"Cp     = {cp:.2f}\\nCpk   = {cpk:.2f}\\nμ       = {mean:.2f} mg\\nσ       = {sigma:.2f} mg\\nStatus: {status}\"\n)\nax.text(\n    0.975,\n    0.96,\n    annotation_text,\n    transform=ax.transAxes,\n    fontsize=8,\n    verticalalignment=\"top\",\n    horizontalalignment=\"right\",\n    family=\"monospace\",\n    bbox={\n        \"boxstyle\": \"round,pad=0.4\",\n        \"facecolor\": ELEVATED_BG,\n        \"edgecolor\": cp_color,\n        \"linewidth\": 1.5,\n        \"alpha\": 0.95,\n    },\n    color=INK,\n)\n\n# Style\ntitle = \"histogram-capability · python · seaborn · anyplot.ai\"\nax.set_xlabel(\"Tablet Weight (mg)\", fontsize=10, color=INK)\nax.set_ylabel(\"Density\", fontsize=10, color=INK)\nax.set_title(title, 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 s in (\"left\", \"bottom\"):\n    ax.spines[s].set_color(INK_SOFT)\nax.yaxis.grid(True, alpha=0.15, linewidth=0.6, color=INK)\n\n# Legend\nlegend_handles = [\n    Line2D([0], [0], color=BLUE, linewidth=2.5, label=\"Parametric Fit (Normal)\"),\n    Line2D([0], [0], color=CYAN, linewidth=2.0, linestyle=\":\", label=\"Empirical KDE (seaborn)\"),\n    Line2D([0], [0], color=RED, linestyle=\"--\", linewidth=2.0, label=f\"LSL = {lsl:.0f} mg\"),\n    Line2D([0], [0], color=RED, linestyle=\"--\", linewidth=2.0, label=f\"USL = {usl:.0f} mg\"),\n    Line2D([0], [0], color=AMBER, linestyle=\"-.\", linewidth=2.0, label=f\"Target = {target:.0f} mg\"),\n]\nax.legend(handles=legend_handles, fontsize=8, loc=\"upper left\", frameon=True, framealpha=0.95)\n\n# Save\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\nplt.close()\n"}