© 2025 Tous droits réservés
Les qqplots sont des graphiques dit “quantile- quantile” qui permettent de comparer visuellement la distribution d’un échantillon avec une distribution théorique (généralement la distribution Normale).
Le principe du QQ plot est de représenter les valeurs observées de l’échantillon sur l’axe des ordonnées, et les quantiles correspondants de la distribution théorique sur l’axe des abscisses.
Si les deux distributions sont similaires, les points devraient être alignés sur une droite diagonale allant du coin inférieur gauche au coin supérieur droit.
Si l’échantillon suit exactement la distribution théorique, les points doivent tomber sur cette ligne.
Si les points s’écartent de cette ligne, cela indique que la distribution de l’échantillon diffère de la distribution théorique.
En voici un exemple, avec la longueur des sépales de l’espèce setosa des données iris (automatiquement présentes dans R), et en utilisant la fonction qqPlot()
du package car
:
library(dplyr)
# preparation des données setosa
setosa <- iris %>%
filter(Species=="setosa")
library(car)
qqPlot(setosa$Sepal.Length)
Sur le principe, les QQ plots ont l’air assez simples, mais lorsqu’on les regarde de plus près, les premières interrogations arrivent assez vite. Par exemple :
Pour essayer de poser tout cela à plat, nous allons réaliser un qqplot en pas à pas
Lorsque le qqplot est employé pour comparer la distribution d’un échantillon à une distribution Normale (Gaussienne), voici les étapes qui sont réalisées :
les données observées sont ordonnées de la plus petite à la plus grande
calcul des rangs de chaque valeur (puisque les données sont ordonnées, le rang vont de 1 à n (nombre total d’observations). Le rang est nécessaire pour l’étape suivante.
calcul de la probabilité cumulée pour chaque valeur observée dans l’échantillon. Il s’agit de la probabilité d’observer une valeur inférieure ou égale à la valeur observée. Ces probabilités renseignent sur la position de chaque valeur dans l’échantillon. Par ex si p=0.5, la valeur considérée est la médiane. Ces probabilités sont nécessaires pour faire le lien avec une distribution Normale. Il existe plusieurs formules pour le faire, les plus courantes sont :
en réalité ce sont les quantiles normaux standardisés qui sont calculés, c’est-à-dire les valeurs qui seraient observées si l’échantillon suivait une loi normale de moyenne =0 et d’écart type = 1.
# simulation de données
set.seed(123) # Pour reproduire les mêmes résultats
valeurs <- round(rgamma(20, shape = 3, rate = 0.5),2)
valeurs
## [1] 3.38 9.47 1.08 5.42 11.89 6.56 1.80 1.03 9.62 6.20 6.35 5.36
## [13] 3.40 9.93 7.95 4.83 3.62 4.34 2.28 4.73
# étape 1 : ordonner
valeurs <- sort(valeurs)
valeurs
## [1] 1.03 1.08 1.80 2.28 3.38 3.40 3.62 4.34 4.73 4.83 5.36 5.42
## [13] 6.20 6.35 6.56 7.95 9.47 9.62 9.93 11.89
# étape 2: calcul des rangs
r <- rank(valeurs)
r
## [1] 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
# étape 3 : calcul des proba cumulées empiriques
p = (r-0.5)/length(valeurs)
p
## [1] 0.025 0.075 0.125 0.175 0.225 0.275 0.325 0.375 0.425 0.475 0.525 0.575
## [13] 0.625 0.675 0.725 0.775 0.825 0.875 0.925 0.975
#étape 4 : calcul des quantiles normaux correspondant aux proba empiriques : valeurs qui seraient observées
# si les données suivaient une loi normales
quantiles_normaux = round(qnorm(p, mean=mean(valeurs), sd=sd(valeurs)),1)
quantiles_normaux
## [1] -0.6 1.0 1.9 2.6 3.1 3.6 4.1 4.5 4.9 5.3 5.7 6.0 6.4 6.9 7.3
## [16] 7.8 8.3 9.0 9.9 11.5
#étape 5 : calcule des quantiles normaux centrés réduits correspondant aux proba empiriques
quantiles_normaux_Std = round(qnorm(p, mean=0, sd=1),1)
quantiles_normaux_Std
## [1] -2.0 -1.4 -1.2 -0.9 -0.8 -0.6 -0.5 -0.3 -0.2 -0.1 0.1 0.2 0.3 0.5 0.6
## [16] 0.8 0.9 1.2 1.4 2.0
Remarque : les valeurs observées sont aussi être appelé des quantiles empiriques (et nous avons cherché à quelle probabilité ils correspondent). C’est de là que vient le terme « quantile quantile plot« , car nous avons d’un côté les quantiles empiriques (en y), et de l’autre, les quantiles standardisés si les données suivaient une loi Normale.
Nous avons à présent toutes les variables nécessaires pour tracer le qqplot :
# assemblage dans un data frame
mydata <- data.frame(valeurs,r, p, quantiles_normaux, quantiles_normaux_Std)
library(ggplot2)
ggplot(mydata, aes(x=quantiles_normaux_Std, y=valeurs))+
geom_point()
Vérifions avec la fonction qqPlot()
qqPlot(mydata$valeurs)
Nos points semblent bien placés ! Jusque là, tout va bien ! 😎
C’est là que les chosent se compliquent pour de vrai 😵💫.
En première approche, et parce que les quantiles normaux sont standardisés (c’est-à-dire centrés-réduits) on pourrait penser que :
Faisons un essai :
ggplot(mydata, aes(x=quantiles_normaux_Std, y=valeurs))+
geom_point()+
geom_abline(intercept=mean(mydata$valeurs), slope=sd(mydata$valeurs))+
ggtitle ("1ere test de tracé de la droite")
La droite obtenue ne correspond pas à celle du qqplot réalisé avec la fonction qqPlot
du package car.😰
En lisant un post de Tristan Mahr (https://www.tjmahr.com/quantile-quantile-plots-from-scratch/) j’ai appris que c’est une approche robuste qui est employée pour tracer la droite. Et que l’on peut :
my.intercept <- median(mydata$valeurs)
my.intercept
## [1] 5.095
my.slope <- IQR(mydata$valeurs)/1.349
my.slope
## [1] 2.603781
ggplot(mydata, aes(x=quantiles_normaux_Std, y=valeurs))+
geom_point()+
geom_abline(intercept=5.095, slope=2.66)+
ggtitle ("Tracé robuste de la droite")
C’est effectivement beaucoup mieux ! 🤩
Si vous souhaitez en savoir plus sur le tracé de la droite et de son enveloppe, je vous recommande de lire l’article Q-Q Plots and Worm Plots from Scratch, de Tristan Mahr.
Que pensez-vous de cet article ? Est-ce qu’il vous permet de mieux comprendre comment sont construits les qqplots et comment les interpréter ?
Dites-le-moi en commentaire
© 2025 Tous droits réservés
Enregistrez vous pour recevoir gratuitement mes fiches « aide mémoire » (ou cheat sheets) qui vous permettront de réaliser facilement les principales analyses biostatistiques avec le logiciel R et pour être informés des mises à jour du site.
20 réponses
Excellent article et encore merci
Je viens d’apprendre avec vous le principe de qqplot.
Merci beaucoup !
Super! Merci Clair.
Interessant
C’est très intéressant pour moi je veux votre aide
Je veux qu’on se mette au contacte pour on parle sur les étude statistique de mon thèse de doctorat.merci
C’est un trè bel article, merci pour le partage.
Merci pour le partage
Merci pour cet article clair et utile. J’ai trois questions complémentaires :
1 – existe-t-il une différence fondamentale entre ce QQ plot et la droite de Henry ?
2 – existe-t-il une quantité calculable pour déterminer si les points s’ajustent « assez bien » à la droite ? (par exemple en utilisant les pentes et les ordonnées à l’origine des deux droites ?)
3 – d’où provient la valeur de 1.349 ?
Merci d’avance !
Bonjour,
je ne connais pas bien la droite de Henry, je ne l’ai jamais étudié, mais j’ai l’impression que les concepts sont très proches.
Pour calculer si les points sont ajustés à une droite, on utilise généralement le R2.
Je ne sais pas d’où vient la valeur 1.349, je n’ai pas creusé davantage le sujet.
Bonne continuation
Salut
C’est extraordinaire. Vraiment merci beaucoup. Je viens de mieux comprendre le QQplot
C’est vraiment intéressant
Merci pour l’exposé clair et intéressant
Bonjour et merci beaucoup… Cela m’a été trés bénéfique, je me prends mieux avec le QQplot actuellement…
Waouh il y a deux ans je connaissais rien en state et la de fil a aiguille je deviens bon grâce a vous
Merci encore
Par feignantise, on ne regarde pas souvent le contenu des fonctions… Ce développement est une belle incitation à le faire. J’ignorais l’usage de l’approximation robuste plutôt qu’avec « mean » et « sd ».
Merci beaucoup donc !
C’est très Clair(e), comme toujours ! Merci pour ces explications détaillées mises à la portée du plus grand nombre.
Top, merci beaucoup!!!
Bonjour,
Merci comme toujours pour ce tutoriel. Ce site reste comme toujours une véritable mine d’info.
Par contre dans la dernière partie de code ne doit-on pas plutot avoir (modif sur les valeurs d’argument de geom_abline) :
ggplot(mydata, aes(x=quantiles_normaux_Std, y=valeurs))+
geom_point()+
geom_abline(intercept=5.095, slope=2.603781)+
ggtitle (« Tracé robuste de la droite »)
Ce qui semble être le cas du graphique.
Bonjour François,
Mais oui, complètement ! Merci d’avoir repéré la coquille, c’est corrigé !