Learn R Programming  /  Base Graphics  /  QQ Plot

QQ Plot

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.