Home > Blockchain >  Add line between errorbar in ggplot in R
Add line between errorbar in ggplot in R

Time:09-29

Context

I used ggplot to draw a grouped error bar graph. I want to connect the points with lines within each group.

I tried to use geom_line(), but the result is not what I want.

Question

Is there any way to connect the points within each group with a line, like the red line in the figure below.

Reproducible Code

dat_a = structure(list(exposure = c("HDL", "HDL", "HDL", "HDL", "HDL", 
"HDL", "HDL", "HDL", "HDL"), event = c("mRS", "mRS", "mRS", "mRS", 
"mRS", "mRS", "mRS", "mRS", "mRS"), model = structure(c(1L, 1L, 
1L, 2L, 2L, 2L, 3L, 3L, 3L), levels = c("low", "middle", "high"
), class = "factor"), group = c("middle", "low", "high", "middle", 
"low", "high", "middle", "low", "high"), margin = c(0.292, 0.372, 
0.349, 0.25, 0.336, 0.281, 0.252, 0.35, 0.278), LL = c(0.273, 
0.327, 0.308, 0.23, 0.287, 0.235, 0.226, 0.285, 0.22), UL = c(0.311, 
0.417, 0.391, 0.27, 0.385, 0.326, 0.278, 0.415, 0.336)), row.names = c(NA, 
-9L), class = c("tbl_df", "tbl", "data.frame"))

pd = position_dodge(.7)

ggplot(dat_a, aes(colour=group, y=margin, x=model, group=group)) 
  geom_point(position=pd,shape=16,size=4) 
  geom_errorbar(aes(ymax = UL, ymin=LL), position=pd,width=0.2,size=1.1) 
  labs(title = "", x="", y="Marginal probability of poor prognosis")  
  guides(color=guide_legend(title="HDL cholesterol level")) 
  scale_color_jama() 
  theme_classic() 
  theme(axis.title =element_text(size=14),axis.text = element_text(size = 12),
        legend.text=element_text(size=12),legend.title = element_text(size=12),
        legend.position = 'right')  ylim(0.2,0.5)

enter image description here

CodePudding user response:

Dodging and lines is always a bit tricky. The issue is that on the one hand we want the lines to be grouped by model but on the other hand we want them to be grouped by group for the dodging. TBMK there is no way to achieve that via dodging and the group aes. Instead I would go for manual dodging which requires to compute the x positions for the geom_line manually. To this end convert your model and group columns to numerics first. Second, rescale the group_num to a range of -1 to 1. This resealed column will be used to "shift" the points for each category of model. Third, compute the amount of the shift which is simply the width used for dodging divided by the number of groups:

enter image description here

library(ggplot2)
library(ggsci)

dw <- .7
dw_line <- dw / length(unique(dat_a$group))
pd <- position_dodge(width)

dat_a$model_num <- as.numeric(factor(dat_a$model))
dat_a$group_num <- as.numeric(factor(dat_a$group))
dat_a$group_num <- scales::rescale(dat_a$group_num, to = c(-1, 1))

ggplot(dat_a, aes(colour = group, y = margin, x = model, group = group))  
  geom_point(position = pd, shape = 16, size = 4)  
  geom_errorbar(aes(ymax = UL, ymin = LL), position = pd, width = 0.2, size = 1.1)  
  geom_line(aes(x = model_num   dw_line * group_num, group = model), color = "red", size = 2)  
  labs(title = "", x = "", y = "Marginal probability of poor prognosis")  
  guides(color = guide_legend(title = "HDL cholesterol level"))  
  scale_color_jama()  
  theme_classic()  
  theme(
    axis.title = element_text(size = 14), axis.text = element_text(size = 12),
    legend.text = element_text(size = 12), legend.title = element_text(size = 12),
    legend.position = "right"
  )  
  ylim(0.2, 0.5)
  • Related