{"spec_id":"pp-basic","library":"makie","language":"julia","code":"# anyplot.ai\n# pp-basic: Probability-Probability (P-P) Plot\n# Library: makie 0.22.10 | Julia 1.11.9\n# Quality: 87/100 | Created: 2026-06-09\n\nusing CairoMakie\nusing ColorSchemes\nusing Colors\nusing Random\nusing Statistics\n\nRandom.seed!(42)\n\n# Theme tokens\nconst THEME    = get(ENV, \"ANYPLOT_THEME\", \"light\")\nconst PAGE_BG  = THEME == \"light\" ? colorant\"#FAF8F1\" : colorant\"#1A1A17\"\nconst INK      = THEME == \"light\" ? colorant\"#1A1A17\" : colorant\"#F0EFE8\"\nconst INK_SOFT = THEME == \"light\" ? colorant\"#4A4A44\" : colorant\"#B8B7B0\"\n\nconst ANYPLOT_SEQ = cgrad([colorant\"#009E73\", colorant\"#4467A3\"])\n\n# Data — process measurements (coating thickness, micrometers) with a right-skewed tail\n# 85% from a normal base distribution, 15% with a positive boost → slightly right-skewed\nn = 200\nbase_measurements = 50.0 .+ 8.0 .* randn(n)\nboost_flags       = Float64.(rand(n) .< 0.15)\nboost_amounts     = 20.0 .+ 5.0 .* abs.(randn(n))\ncoating_thickness = base_measurements .+ boost_flags .* boost_amounts\n\n# Standardise to zero mean, unit variance for P-P comparison against N(0,1)\nμ_fit    = mean(coating_thickness)\nσ_fit    = std(coating_thickness)\nz_scores = (coating_thickness .- μ_fit) ./ σ_fit\n\n# Sort and compute empirical CDF (Hazen plotting positions: (i − 0.5) / n)\nsorted_z      = sort(z_scores)\nempirical_cdf = [(i - 0.5) / n for i in 1:n]\n\n# Theoretical normal CDF — Abramowitz & Stegun (1964) rational approximation 26.2.17\n# Maximum absolute error ≤ 7.5e-8; no external packages required.\nabs_z     = abs.(sorted_z)\nt_coeff   = 1.0 ./ (1.0 .+ 0.2316419 .* abs_z)\npoly_val  = t_coeff .* (0.319381530 .+ t_coeff .* (\n            -0.356563782 .+ t_coeff .* (\n             1.781477937 .+ t_coeff .* (\n            -1.821255978 .+ t_coeff .* 1.330274429))))\np_upper   = 1.0 .- (1.0 / sqrt(2π)) .* exp.(-abs_z .^ 2 ./ 2.0) .* poly_val\ntheoretical_cdf = ifelse.(sorted_z .>= 0.0, p_upper, 1.0 .- p_upper)\n\n# Deviation from reference diagonal — key insight: S-curve departure from normality\ndev     = abs.(empirical_cdf .- theoretical_cdf)\nmax_dev = maximum(dev)\n\n# 95% KS confidence band half-width (D_α = 1.36 / √n)\ndelta  = 1.36 / sqrt(n)\nxs_vec = collect(range(0.0, 1.0, length=200))\n\n# Figure — square canvas (P-P plots use equal 0–1 probability axes)\nfig = Figure(\n    size            = (1200, 1200),\n    fontsize        = 14,\n    backgroundcolor = PAGE_BG,\n)\n\nax = Axis(\n    fig[1, 1];\n    title             = \"pp-basic · julia · makie · anyplot.ai\",\n    titlesize         = 28,\n    titlecolor        = INK,\n    xlabel            = \"Theoretical Cumulative Probability\",\n    ylabel            = \"Empirical Cumulative Probability\",\n    xlabelsize        = 20,\n    ylabelsize        = 20,\n    xticklabelsize    = 16,\n    yticklabelsize    = 16,\n    xlabelcolor       = INK,\n    ylabelcolor       = INK,\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    xgridcolor        = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    ygridcolor        = RGBAf(INK.r, INK.g, INK.b, 0.12),\n    xminorgridvisible = false,\n    yminorgridvisible = false,\n    aspect            = AxisAspect(1),\n    limits            = (0.0, 1.0, 0.0, 1.0),\n)\n\n# 95% KS confidence envelope — defines acceptance region around the diagonal\nband!(ax, xs_vec, clamp.(xs_vec .- delta, 0.0, 1.0), clamp.(xs_vec .+ delta, 0.0, 1.0);\n    color = RGBAf(INK.r, INK.g, INK.b, 0.07),\n)\n\n# Reference diagonal — perfect distributional fit\nlines!(ax, [0.0, 1.0], [0.0, 1.0];\n    color     = INK_SOFT,\n    linewidth = 1.5,\n    linestyle = :dash,\n)\n\n# P-P scatter — points colored by absolute deviation from diagonal to highlight S-curve\nscat = scatter!(ax, theoretical_cdf, empirical_cdf;\n    color       = dev,\n    colormap    = ANYPLOT_SEQ,\n    colorrange  = (0.0, max_dev),\n    markersize  = 11,\n    strokewidth = 0.5,\n    strokecolor = PAGE_BG,\n)\n\n# Colorbar showing deviation magnitude from reference diagonal\nColorbar(fig[1, 2], scat;\n    label          = \"Deviation from Reference\",\n    labelcolor     = INK,\n    ticklabelcolor = INK_SOFT,\n    tickcolor      = INK_SOFT,\n    labelsize      = 16,\n    ticklabelsize  = 14,\n)\n\n# Save\nsave(\"plot-$(THEME).png\", fig; px_per_unit = 2)\n"}