Search code examples
rggplot2position

ggplot2: How to change the position of a point plot while keep the bar plot in the same position


I want to plot the result of a paried t test with a plot containing points, lines and bars, like the plot on the paper (Bellmund, at al. Mapping sequence structure in the human lateral entorhinal cortex. Elife, 8. doi:10.7554/eLife.45333).

See the screenshot of the plot:

See the screenshot of the plot

In my practise, it is easy to put geom_point, geom_line and geom_bar in the same plot, but the problem comes up when I try to change the positions of the points and lines while remain the bars unchanged.

I tried to use position_dodge() in point plot, however, it would move all the elements in the plot. Any ideas? Thanks for help!

library(ggplot2)

id <- rep(c(1:29), times = 2)
condition <- c(rep('vector.angle', times = 29), rep('baseline', times = 29))
value <- rnorm(58, mean = 22, sd = 27)
v.angle.gg <- data.frame(id, condition, value)

ggplot(data = v.angle.gg, aes(x = condition, y = value)) +
  geom_hline(aes(yintercept = 0), color = "black", size = 1.5, linetype = 14) + 
  stat_summary(fun.y = mean, geom = "bar", aes(x = condition, y = value, fill = condition), 
               width = 0.3, position = position_identity()) + 
  geom_line(aes(group= id), size = 1, color = 'gray') + 
  geom_point(size = 4, position = position_dodge(width= 1)) +
  scale_fill_brewer(palette="Paired") +
  xlab('Conditions') + ylab('Parameter Estimations') +
  theme(
    title = element_text(size=rel(1.3),face="bold", colour = "black"), 
    axis.line.x = element_line(size = 1, colour = "black"),
    axis.text.x=element_text(size=rel(1.3),face="bold", colour = "black"),
    axis.ticks.x = element_line(size=rel(2), colour = "black"),
    axis.line.y = element_line(size = 1, colour = "black"),
    axis.text.y=element_text(size=rel(1.3),face="bold", colour = "black"),
    axis.ticks.y = element_line(size=rel(2), colour = "black"),
    panel.border = element_blank(),
    panel.background = element_blank(),
    panel.grid = element_blank()
  ) + 
  guides(fill=F,color=F) 

Solution

  • The question asks for ideas, here is a hack.

    Bar plots plot the bars at consecutive integers x, in this case c(1, 2). So you need the points and the lines connecting them at c(1.2, 1.8). Now, in the data set column condition has the alphabetically larger values first and they will be coerced to factor before plotting. So the new x coordinates vector will be subset with condition correctly. Not clear?

    f <- v.angle.gg$condition
    f <- c(1.2, 1.8)[as.integer(factor(f))]
    

    These are the new coordinates. And they must be set in both geom_line and geom_point. Makes more sense now? I hope so.
    I have simplified the graph so that only the relevant part is plotted.

    ggplot(data = v.angle.gg, aes(x = condition, y = value)) +
      geom_hline(aes(yintercept = 0), color = "black", size = 1.5, linetype = 14) + 
      stat_summary(fun = mean, geom = "bar", aes(x = condition, y = value, fill = condition), 
                   width = 0.3, position = position_identity()) + 
      geom_line(aes(x = f, group= id), size = 1, color = 'gray') + 
      geom_point(aes(x = f), size = 4, position = position_dodge(width= 1))
    

    enter image description here