Interval Plot


An interval plot is used to compare groups similar to a box plot or a dot plot. It is used when the data is continuous. Instead of plotting the individual data point, an interval plot shows the confidence interval for the mean of the data. This post describes how to build an interval plot with R, using ggplot2 or plotrix.

Data


# Creation of dataset
set.seed(923874)                
data <- data.frame(visit = rep(1:10, each=2),
                   value = round(runif(20, 10, 20),2),
                   lower = round(runif(20, 0, 10),2),
                   upper = round(runif(20, 20, 30),2),
                   n = sample(5:10, size=20, replace=T),
                   group = rep(c('A', 'B'), 10))

Interval plot using ggplot2 package


Here, we will be using the geom_point() function to plot the points and then the geom_errorbar() function to add the confidence intervals to the plot.

# Libraries
library(ggplot2)

min_y <- floor(min(data$lower[data$group=='A'],na.rm=T))
max_y <- ceiling(max(data$upper[data$group=='A'],na.rm=T))

figure <- ggplot(data[data$group=='A',], aes(visit, value)) +
  geom_point(color="#0099B4FF") +
  geom_line(size=0.5, color="#0099B4FF") +
  geom_errorbar(aes(ymin = lower, ymax = upper), size=0.5, width=0.3, color="#0099B4FF") +
  labs(x = "Time (months)") +
  scale_x_continuous(breaks = seq(0, max(data$visit), 1)) +
  scale_y_continuous(breaks = seq(min_y, max_y, 5), limits = c(min_y, max_y)) +
  scale_color_manual(values=c("#69b3a2", "#404080")) +
  theme_classic() +
  theme(axis.title = element_text(size=9),
        legend.position = "top")

table <- ggplot(data[data$group=='A',], aes(x = visit, y = factor(1), label = n)) +
  geom_text(cex=3) +
  theme(
    panel.grid.major = element_blank(), 
    plot.background = element_blank(), 
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    legend.position = "none",
    axis.line = element_blank(),
    axis.text.x = element_blank(),
    axis.text.y = element_blank(),
    axis.ticks = element_blank(),
    axis.ticks.x = element_blank(),  
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    plot.title = element_blank(), 
    panel.background = element_rect("white")
  ) + 
  scale_x_continuous(breaks = seq(0, max(data$visit), 1),
                     expand = c(0.07,-0.07)) +
  scale_y_discrete(name = "Number \n of patients")

ggpubr::ggarrange(figure, table, nrow=2, heights=c(0.8, 0.15), align = "v")

We add a parameter to see the dotplot for the groups A and B simultaneously.

min_y <- floor(min(data$lower,na.rm=T))
max_y <- ceiling(max(data$upper,na.rm=T))

figure <- ggplot(data, aes(visit, value, col=group)) +
  geom_point() +
  geom_line(size=0.5) +
  geom_errorbar(aes(ymin = lower, ymax = upper), size=0.5, width=0.3) +
  labs(x = "", col="Arm") +
  scale_x_continuous(breaks = seq(1, max(data$visit), 1),
                     labels = paste("Visit",1:10)) +
  scale_y_continuous(breaks = seq(min_y, max_y, 5), limits = c(min_y, max_y)) +
  scale_color_manual(values=c("#69b3a2", "#404080")) +
  theme_classic() +
  theme(axis.title = element_text(size=9),
        legend.position = "top")

# reverse the order of the labels to get the right order in the table :
data$group_rev <- factor(data$group, levels=c('B','A'))
table <- ggplot(data, aes(x = visit, y = group_rev, label = n)) +
  geom_text(cex=3, check_overlap = TRUE) +
  theme(
    panel.grid.major = element_blank(), 
    plot.background = element_blank(), 
    panel.grid.minor = element_blank(),
    panel.border = element_blank(),
    legend.position = "none",
    axis.line = element_blank(),
    axis.text.x = element_blank(),
    axis.ticks = element_blank(),
    axis.ticks.x = element_blank(),  
    axis.title.x = element_blank(),
    axis.title.y = element_text(size = 10),
    plot.title = element_blank(), 
    panel.background = element_rect("white")
  ) + 
  scale_x_continuous(breaks = seq(1, max(data$visit), 1),
                     labels = paste("Visit",1:10),
                     expand = c(0.07,-0.07)) +
  scale_y_discrete(name = "Number \n of patients")

ggpubr::ggarrange(figure, table, nrow=2, heights=c(0.8, 0.15), align = "v")

Interval plot using plotrix package


This example explains how to use the plotrix package to draw a confidence interval plot.

# Libraries
library(plotrix)

plotCI(x = data$visit[data$group=='A'],              
       y = data$value[data$group=='A'],
       li = data$lower[data$group=='A'],
       ui = data$upper[data$group=='A'])




Contact

This document is a work of the statistics team in the Biostatistics and Medical Information Department at Saint-Louis Hospital in Paris (SBIM).
Developed and updated by Noémie Bigot and Anouk Walter-Petrich
noemie.bigot@aphp.fr; anouk.walter-petrich@u-paris.fr

Based on The R Graph Gallery by Yan Holtz.

SBIM