Search code examples
rggplot2r-forestplot

Inconsistent alignment of data in plot


I have a df like this

data <- data.frame(CAR.HEIGHT = c("LOW","MODERATE","WHOLE"),
                     OR = c(1.077,1.044,1.050),
                     up_ci = c(1.099,1.054,1.059),
                     LOW_ci = c(1.055,1.034,1.041),
                     N = c(41607,188529,230136))

I have created a forest plot using ggplot2. code included below.

library (ggplot2)
library(reshape2)
library(forcats)

pos.x <- 1.4

gg<- data %>%
    mutate(CAR.HEIGHT = fct_relevel(CAR.HEIGHT,"WHOLE", "MODERATE", "LOW")) %>%

    ggplot(aes(x= OR, y= CAR.HEIGHT,)) +
    
    geom_point(size=6,shape=20) +
    
    geom_vline(xintercept = 1, colour = 'red')+
    
    geom_errorbar(aes(xmin= LOW_ci,xmax= up_ci),width=0.30) +
    
    coord_cartesian(xlim = c(0.80,1.25), expand = FALSE,
                    clip = 'off') +
    
    geom_text(color='Black',aes(label = 'OR' , x = pos.x-0.27, y = 3.9),
              hjust = 1.3,size=3.3) +
    
    geom_text(position = position_dodge(width = 0.3),color='Black',
              aes(label = paste(round(OR,3)), x =pos.x-0.285,
                  y = CAR.HEIGHT),
              hjust = 0,size=3.3) +
    
    geom_text(color='Black',aes(label = '95% CI' , x = pos.x-0.25, y = 3.9),
              hjust = 0,size=3.3) +
    
    geom_text(position = position_dodge(width = 0.6),color='Black',
              aes(label = paste("(",round(LOW_ci,2),', ',round(up_ci,2),")",sep=''),
                  x =pos.x-0.25, y = CAR.HEIGHT),
              hjust = 0,size=3.3) +
    
    geom_text(color='Black',aes(label = 'N' , x = pos.x-0.201, y = 3.9),
              hjust = 0,size=3.3) +
    
    geom_text(position = position_dodge(width = 0.6),color='Black',
              aes(label = paste(round(N,3)), x =pos.x-0.234,
                  y = CAR.HEIGHT),
              hjust = -1.21,size=3.3) +
    
    xlab("TEST CAR")+ ylab("CAR HEIGHT")

However, for some reason, the one of the data in column N (41607) does not align in a straight line with the others.

Output I have changed the hjust severally, but the issue is still there. Any idea on how to navigate round this will be appreciated.


Solution

  • You should avoid using hjust to tweak a label's position. Decide on a point where you want the text to be using x and y co-ordinates, then decide how to place the text relative to that point using hjust: use hjust = 0 for left justified, hjust = 0.5 for centered and hjust = 1 for right-justified.

    Although you can set hjust to other values to move the string about, the amount that the text moves is always related to the string's length, so if you have strings of different sizes, they will move different amounts even if their hjust is set to the same value. In general, if you are using hjust or vjust to tweak string position, you are probably using them incorrectly.

    Simply use your x aesthetic (or position_nudge) to specfiy where you want the text and how you want it aligned.

    Note that if you are going to add text annotations for the table headers, it is easier and requires less code if you do this using annotate instead of geom_text; note that the following code is much shorter than the original:

    data %>%
      mutate(CAR.HEIGHT = fct_relevel(CAR.HEIGHT,"WHOLE", "MODERATE", "LOW")) %>%
      ggplot(aes(OR, CAR.HEIGHT)) +
      geom_point(size = 6, shape = 20) +
      geom_vline(xintercept = 1, colour = 'red') +
      geom_errorbar(aes(xmin = LOW_ci, xmax = up_ci), width = 0.30) +
      annotate('text', pos.x - c(0.27, 0.22, 0.17), 3.9,
               label = c('OR', '95% CI', 'N'), size = 3.3, fontface = 2) +
      geom_text(aes(label = paste(round(OR,3)), x = pos.x - 0.27),
                hjust = 0.5, size = 3.3) +
      geom_text(aes(label = paste0("(", round(LOW_ci,2), ',' , round(up_ci,2),")"),
                    x = pos.x - 0.22),
                hjust = 0.5, size = 3.3) +
      geom_text(aes(label = paste(round(N,3)), x = pos.x - 0.17),
                size=3.3, hjust = 0.5) +
      labs(x = "TEST CAR", y = "CAR HEIGHT") +
      coord_cartesian(xlim = c(0.80,1.25), expand = FALSE, clip = 'off')
    

    enter image description here