A Quantile-Quantile (QQ) plot compares your data's distribution to a theoretical normal distribution. It is a key diagnostic step before many statistical tests that assume normality.
How to Read a QQ Plot
Each point compares one of your data\'s quantiles to the matching quantile of a perfect normal distribution. If the data is approximately normal, the points fall close to a straight diagonal line.
QQ Plot of Normally-Distributed Data
R Code
set.seed(1) normal_data <- rnorm(200, mean = 50, sd = 10) qqnorm(normal_data, main = "QQ Plot of Normal Data") qqline(normal_data, col = "red", lwd = 2)
QQ Plot of Skewed Data
Compare that to skewed data, generated from an exponential distribution — notice how the points curve away from the line at the ends.
R Code
skewed_data <- rexp(200, rate = 0.1) qqnorm(skewed_data, main = "QQ Plot of Skewed Data") qqline(skewed_data, col = "red", lwd = 2)
Backing Visual Judgement with a Formal Test
💡 Tip
A QQ plot is a visual, somewhat subjective check. Pair it with a formal test like shapiro.test() for a numeric p-value, especially with small sample sizes where visual patterns can be misleading.R Code
shapiro.test(normal_data) shapiro.test(skewed_data)
Output
Shapiro-Wilk normality test data: normal_data W = 0.995, p-value = 0.7 Shapiro-Wilk normality test data: skewed_data W = 0.82, p-value = 1.2e-13
Advanced: Checking Regression Residuals
🚀 Advanced Example
QQ plots are used constantly to check the residuals of a fitted regression model, not just raw data - a required assumption check before trusting a linear model\'s p-values.R Code
model <- lm(dist ~ speed, data = cars) # built-in R dataset qqnorm(residuals(model), main = "QQ Plot of Model Residuals") qqline(residuals(model), col = "red")
Key Points
- qqnorm() plots your data against theoretical normal quantiles; qqline() adds the reference line.
- Points hugging the line suggest approximate normality; curves at the ends suggest skew.
- shapiro.test() gives a formal p-value to back up the visual check.
- QQ plots are routinely used to check regression residuals, not just raw data.