{"spec_id":"pp-basic","library":"seaborn","language":"python","code":"\"\"\" anyplot.ai\npp-basic: Probability-Probability (P-P) Plot\nLibrary: seaborn 0.13.2 | Python 3.13.13\nQuality: 87/100 | Updated: 2026-06-16\n\"\"\"\n\nimport os\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport pandas as pd\nimport seaborn as sns\nfrom matplotlib.colors import LinearSegmentedColormap\nfrom scipy import stats\n\n\n# Theme tokens (see prompts/default-style-guide.md \"Theme-adaptive Chrome\")\nTHEME = os.getenv(\"ANYPLOT_THEME\", \"light\")\nPAGE_BG = \"#FAF8F1\" if THEME == \"light\" else \"#1A1A17\"\nINK = \"#1A1A17\" if THEME == \"light\" else \"#F0EFE8\"\nINK_SOFT = \"#4A4A44\" if THEME == \"light\" else \"#B8B7B0\"\n\n# Imprint sequential colormap — single-polarity (brand green -> blue)\nimprint_seq = LinearSegmentedColormap.from_list(\"imprint_seq\", [\"#009E73\", \"#4467A3\"])\n\n# Data — Manufacturing QC: do steel-bolt tensile strengths (MPa) follow a normal distribution?\n# A main production batch plus a slightly skewed tail from over-hardened bolts.\nnp.random.seed(42)\nsample_size = 200\nmain_batch = np.random.normal(loc=520, scale=35, size=int(sample_size * 0.85))\nhardened_bolts = np.random.exponential(scale=18, size=int(sample_size * 0.15)) + 560\ntensile_strengths = np.concatenate([main_batch, hardened_bolts])\n\n# P-P coordinates: empirical CDF (plotting position) vs fitted-normal theoretical CDF\nsorted_strengths = np.sort(tensile_strengths)\nempirical_cdf = np.arange(1, len(sorted_strengths) + 1) / (len(sorted_strengths) + 1)\nmu, sigma = stats.norm.fit(sorted_strengths)\ntheoretical_cdf = stats.norm.cdf(sorted_strengths, loc=mu, scale=sigma)\ndeviation = np.abs(empirical_cdf - theoretical_cdf)\n\ndf = pd.DataFrame({\"theoretical\": theoretical_cdf, \"empirical\": empirical_cdf, \"deviation\": deviation})\n\n# Plot — square canvas keeps the 45-degree diagonal meaningful (6 x 6 in @ 400 dpi = 2400 x 2400 px)\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    },\n)\n\nfig, ax = plt.subplots(figsize=(6, 6), dpi=400)\nfig.set_facecolor(PAGE_BG)\nax.set_facecolor(PAGE_BG)\n\n# 45-degree reference line — perfect distributional fit\nax.plot([0, 1], [0, 1], color=INK_SOFT, linewidth=2.0, linestyle=\"--\", alpha=0.7, zorder=1)\n\n# P-P scatter, coloured by absolute deviation from the fitted normal\nsns.scatterplot(\n    data=df,\n    x=\"theoretical\",\n    y=\"empirical\",\n    hue=\"deviation\",\n    palette=imprint_seq,\n    s=45,\n    alpha=0.8,\n    edgecolor=PAGE_BG,\n    linewidth=0.5,\n    legend=False,\n    zorder=2,\n    ax=ax,\n)\n\n# Colorbar for the deviation encoding\nnorm = plt.Normalize(df[\"deviation\"].min(), df[\"deviation\"].max())\nsm = plt.cm.ScalarMappable(cmap=imprint_seq, norm=norm)\nsm.set_array([])\ncbar = fig.colorbar(sm, ax=ax, shrink=0.6, aspect=22, pad=0.02)\ncbar.set_label(\"Absolute deviation from normal fit\", fontsize=10, color=INK)\ncbar.ax.tick_params(labelsize=8, colors=INK_SOFT)\ncbar.outline.set_edgecolor(INK_SOFT)\n\n# Style\nax.set_xlabel(\"Theoretical cumulative probability (normal)\", fontsize=10, color=INK)\nax.set_ylabel(\"Empirical cumulative probability\", fontsize=10, color=INK)\nax.set_title(\"pp-basic · python · seaborn · anyplot.ai\", fontsize=12, fontweight=\"medium\", color=INK)\nax.tick_params(axis=\"both\", labelsize=8, colors=INK_SOFT)\nax.set_xlim(-0.02, 1.02)\nax.set_ylim(-0.02, 1.02)\nax.set_aspect(\"equal\")\nax.grid(True, linewidth=0.8)\nsns.despine(ax=ax)\nfor spine in ax.spines.values():\n    spine.set_color(INK_SOFT)\n\n# Save — bbox_inches stays default (None) so figsize x dpi yields the exact 2400 x 2400 canvas\nplt.savefig(f\"plot-{THEME}.png\", dpi=400, facecolor=PAGE_BG)\n"}