13.1 Contour plot
A contour plot is a graphical representation where contour lines connect points of equal value. It is particularly useful for visualizing interactions between two continuous variables.
Let’s consider the risk of cardiovascular disease (CVD) as a function of three predictors: age, cholesterol level, and smoking.
y=β0+β1x1+β2x2+β3x3
where y is the response variable (CVD), x1 and x2 are age and cholesterol, respectively. While x3 is the interaction term given by the product of the two predictors, x1×x2.
y=β0+β1x1+β2x2+β3(x1×x2)
We can visualize the interaction effect between age and cholesterol on CVD risk using a contour plot. The contour lines will show how the risk of CVD changes with different combinations of age and cholesterol levels.
To visualize if within this data there is a interaction effect between variables, and what type of interaction effect it is, we can use a contour plot.
Imagine these are the coefficients for the model, we can create a contour plot to visualize the interaction effect between two predictors, x1 and x2.
library(tidyverse)
set.seed(123)
beta0<- rep(0,200)
beta1<- rep(1,200)
beta2<- rep(1,200)
x1<- runif(200, min = 0, max = 1)
x2 <- runif(200, min = 0, max = 1)
e <- rnorm(200)
Then we simulate the interaction effect using three different scenarios: antagonism, additive (no interaction), and synergism.
β3≈0, it indicates no interaction effect, meaning that the risk of CVD is simply the sum of the individual effects of age and cholesterol without any additional interaction.
β3>0, it indicates that the interaction effect is positive, meaning that as both age and cholesterol increase, the risk of CVD increases more than if they were considered independently. Conversely,
β3<0, it suggests a negative interaction effect, meaning that the risk of CVD does not increase as much with increasing age and cholesterol.
beta3_antagonism <- rep(-10,200) # Antagonism
beta3_additive <- rep(0,200) # Additive (no interaction)
beta3_synergism <- rep(10,200) # Synergism
We build three models to represent the three different interaction effects: antagonism, additive, and synergism.
y1 = beta0 + beta1*x1 + beta2*x2 + beta3_antagonism*(x1*x2) + e
y2 = beta0 + beta1*x1 + beta2*x2 + beta3_additive*(x1*x2) + e
y3 = beta0 + beta1*x1 + beta2*x2 + beta3_synergism*(x1*x2) + e
observed1 <- tibble(y1, x1, x2)
observed2 <- tibble(y2, x1, x2)
observed3 <- tibble(y3, x1, x2)
mod1 <- lm(y1 ~ x1*x2, data = observed1)
mod2 <- lm(y2 ~ x1*x2, data = observed2)
mod3 <- lm(y3 ~ x1*x2, data = observed3)
observed1$z <- predict(mod1, observed1)
observed2$z <- predict(mod2, observed2)
observed3$z <- predict(mod3, observed3)
We need to create a grid of points to plot the contour lines. This grid will cover the range of values for x1 and x2.
grid1 <- with(observed1,
interp::interp(x = x1, y = x2, z))
griddf1 <- subset(data.frame(x = rep(grid1$x, nrow(grid1$z)),
y = rep(grid1$y,
each = ncol(grid1$z)),
z = as.numeric(grid1$z)),!is.na(z))
grid2 <- with(observed2,
interp::interp(x = x1, y = x2, z))
griddf2 <- subset(data.frame(x = rep(grid2$x, nrow(grid2$z)),
y = rep(grid2$y,
each = ncol(grid2$z)),
z = as.numeric(grid2$z)),!is.na(z))
grid3 <- with(observed3,
interp::interp(x = x1, y = x2, z))
griddf3 <- subset(data.frame(x = rep(grid3$x, nrow(grid3$z)),
y = rep(grid3$y,
each = ncol(grid3$z)),
z = as.numeric(grid3$z)),!is.na(z))
We can now create the contour plots for each of the three scenarios using ggplot2
. Each plot will show the contour lines representing the predicted values of y based on the interaction between x1 and x2.
p1 <- ggplot(griddf1, aes(x, y, z = z)) +
geom_contour(aes(colour = after_stat(level),
linetype = factor(after_stat(level))),
linewidth = 2) +
scale_color_viridis_c() +
guides(linetype = "none") +
labs(title="Antagonism",
color="Prediction", x = "x1", y = "x2") +
theme(legend.position = "top")
p2 <- ggplot(griddf2, aes(x, y, z = z)) +
geom_contour(aes(colour = after_stat(level),
linetype = factor(after_stat(level))),
linewidth = 2) +
scale_color_viridis_c()+
guides(linetype = "none")+
labs(title="Additive (no interaction)",
color="Prediction", x = "x1", y = "x2")+
theme(legend.position = "top")
p3 <- ggplot(griddf3, aes(x, y, z = z)) +
geom_contour(aes(colour = after_stat(level),
linetype = factor(after_stat(level))),
linewidth = 2) +
scale_color_viridis_c()+
guides(linetype = "none")+
labs(title="Synergism",
color="Prediction", x = "x1", y = "x2")+
theme(legend.position = "top")
Combine the three contour plots using patchwork: