Diagramme Q–Q avec bande de confiance

Diagrammes quantile-quantile normaux avec enveloppe à 95 %, pour une variable brute et sa version logarithmique.

Diagramme Q–Q avec bande de confiance

Un diagramme quantile-quantile confronte les données triées et standardisées aux quantiles que produirait une loi normale. Des données normales s'alignent sur la diagonale ; un motif courbé, en forme de banane, signale une asymétrie. La bande ombrée est une enveloppe ponctuelle à 95 % construite à partir de la loi bêta des statistiques d'ordre normales : les points situés à l'extérieur sont plus extrêmes que ce que le hasard permet.

Les données sont les revenus de 235 ménages ouvriers belges (données d'Engel sur les dépenses alimentaires, fournies avec statsmodels). Le panneau de gauche montre le revenu brut, celui de droite son logarithme. Les quantiles proviennent de scipy.stats.norm.ppf, l'enveloppe de scipy.stats.beta.ppf, et chaque panneau rapporte un test de Shapiro–Wilk.

Le code et le texte à l'intérieur des figures sont en anglais.

qq-plot.py · 43 lignes
Télécharger GitHub
import matplotlib.pyplot as plt
import numpy as np
import statsmodels.api as sm
from scipy import stats

# Data: household income, raw and log-transformed
income = sm.datasets.engel.load_pandas().data["income"].to_numpy()
samples = {"Raw income": income, "Log income": np.log(income)}
palette = ["#FF9500", "#007AFF"]

fig, axes = plt.subplots(1, 2, figsize=(10, 5), sharex=True, sharey=True)
for ax, (name, x), c in zip(axes, samples.items(), palette):
    n = len(x)
    z = np.sort((x - x.mean()) / x.std(ddof=1))      # standardised sample quantiles
    pp = (np.arange(1, n + 1) - 0.5) / n              # plotting positions
    theo = stats.norm.ppf(pp)                         # theoretical normal quantiles

    # 95% pointwise envelope: order statistic i of a uniform sample is Beta(i, n-i+1)
    i = np.arange(1, n + 1)
    lo = stats.norm.ppf(stats.beta.ppf(0.025, i, n - i + 1))
    hi = stats.norm.ppf(stats.beta.ppf(0.975, i, n - i + 1))
    outside = (z < lo) | (z > hi)

    ax.fill_between(theo, lo, hi, color="#8E8E93", alpha=0.18, lw=0, label="95% envelope")
    ax.plot([-3.5, 3.5], [-3.5, 3.5], color="#8E8E93", lw=1, ls="--")
    ax.scatter(theo[~outside], z[~outside], s=16, color=c, alpha=0.7, lw=0)
    ax.scatter(theo[outside], z[outside], s=22, color="#FF3B30", lw=0,
               label=f"outside band ({outside.sum()})")

    W, p = stats.shapiro(x)
    ax.set_title(name, pad=20, fontsize=12)
    ax.text(0, 1.02, f"Shapiro–Wilk W = {W:.3f}, p = {p:.1e} · n = {n}",
            transform=ax.transAxes, fontsize=9.5, color="#6E6E73")
    ax.legend(loc="upper left")
    ax.grid(axis="x")
    ax.set_xlabel("Theoretical normal quantiles")

axes[0].set_ylabel("Standardised sample quantiles")
axes[0].set_xlim(-3.2, 3.2)
axes[0].set_ylim(-3.3, 4.6)
fig.suptitle("Taking logs brings household income much closer to normal",
             x=0.01, ha="left", fontsize=14)
plt.show()

Les figures utilisent le style PyStatlas (facultatif) : ajoutez plt.style.use("pystatlas.mplstyle") pour obtenir exactement le même rendu.

Source des données

  • Engel's Belgian household budgets (235 families). Koenker, R., & Bassett, G. (1982). Robust tests for heteroscedasticity based on regression quantiles. Econometrica, 50(1), 43–61. https://doi.org/10.2307/1912528
    Engel's (1857) household budget data as used by Koenker and Bassett and distributed with R's quantreg; in statsmodels as sm.datasets.engel; public domain.

Les exemples illustrent des méthodes statistiques. Leurs titres décrivent ce que chaque figure montre dans ces données précises — souvent un échantillon restreint, daté ou partiel —, et non la position de l'auteur sur la question de fond. Pour l'interprétation, le contexte et la qualité des données, reportez-vous aux sources originales citées ici.

Comment citer

PyStatlas est créé et maintenu par Thierry Warin. S'il vous a été utile dans vos travaux, merci de le citer.

Warin, T. (2026). Q–Q plot with confidence band. In PyStatlas: A Python Gallery of Statistical Graphics for the Social Sciences. https://warint.github.io/pystatlas/distributions/qq-plot/

@misc{warin2026statlas,
  author       = {Warin, Thierry},
  title        = {PyStatlas: A Python Gallery of Statistical Graphics for the Social Sciences},
  year         = {2026},
  howpublished = {\url{https://warint.github.io/pystatlas/}},
  note         = {Source code: https://github.com/warint/pystatlas}
}

Plus dans Distributions