Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get geom_errorbar to "dodge" correctly on a bar chart in ggplot2?

Tags:

r

ggplot2

I'm trying to make a grouped bar chart with error bars. However, I can't get the error bars to both look correct (i.e., be thinner than the main bars) and positioned correctly (in the center of the bars). The position option and position_dodge() don't seem to be working correctly, and I can't figure out why--based on examples in other similar questions, this ought to work.

I'm running ggplot2 version 3.0.0 in R version 3.4.2.

A minimal working example:

d<-data.frame(bin = factor(c(1,2,3,1,2,3)),type = factor(c(1,1,1,2,2,2)), beta = c(10,20,30,40,50,60), se = c(2,2,2,2,2,2))
ggplot(d, aes(x=bin,y=beta,ymin = beta - 1.96* se, ymax = beta+1.96* se)) + 
    geom_bar(aes(fill = type), position = position_dodge2(), stat="identity")  +
    geom_errorbar(position=position_dodge2(.9))

Produces:Right Position, Too Wide Right position, but too wide. Using position_dodge() instead of position_dodge2() doesn't even get the position right:

ggplot(d, aes(x=bin,y=beta,ymin = beta - 1.96* se, ymax = beta+1.96* se)) + 
  geom_bar(aes(fill = type), position = position_dodge(), stat="identity")  +
  geom_errorbar(position=position_dodge(.9)) 

Even wider, and wrong position Adding the width parameter to geom_errorbar breaks the version with position_dodge2() and doesn't help the one with position_dodge():

ggplot(d, aes(x=bin,y=beta,ymin = beta - 1.96* se, ymax = beta+1.96* se)) + 
  geom_bar(aes(fill = type), position = position_dodge2(), stat="identity")  +
  geom_errorbar(position=position_dodge2(.9), width= .2)

ggplot(d, aes(x=bin,y=beta,ymin = beta - 1.96* se, ymax = beta+1.96* se)) + 
  geom_bar(aes(fill = type), position = position_dodge(), stat="identity")  +
  geom_errorbar(position=position_dodge(.9), width = .2) 

Good width, wrong position Good width, wrong position still

What's going on here? How do I fix this?

like image 677
rsandler Avatar asked Sep 01 '25 22:09

rsandler


1 Answers

If you move fill into the global aes() then position_dodge() will work as expected. Alternatively you could add the grouping variable via group to geom_errorbar().

ggplot(d, aes(x = bin, y = beta, 
              ymin = beta - 1.96*se, ymax = beta+1.96*se, fill = type)) + 
    geom_bar(position = position_dodge(), stat="identity")  +
    geom_errorbar(position=position_dodge(.9), width = .2)

The issue with position_dodge2() appears to be what is discussed in this GitHub issue, which can be solved via the padding argument. Notice there is no longer a width argument in geom_errorbar() with this approach.

ggplot(d, aes(x = bin, y = beta, 
              ymin = beta - 1.96*se, ymax = beta+1.96*se, fill = type)) + 
    geom_bar(position = position_dodge2(), stat="identity")  +
    geom_errorbar(position = position_dodge2(.9, padding = .6))
like image 68
aosmith Avatar answered Sep 03 '25 13:09

aosmith