Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Problem placing error bars at the center of the columns in ggplot()

I am having a problem with my bar chart- the error bars just appear on the corner of the columns of the grouping variable rather than on them in a centralised way. The code I am using is this:

a <- data.frame (Cond = c("In", "In", "Out", "Out"),
                Temp = c("Hot", "Cool", "Hot", "Cool"),
                Score = c(.03, -.15, 0.84, 0.25),
                SE = c(.02, .08, .14, .12))
a.bar <- ggplot (data = a, aes(x = Cond, y = Score, fill = Temp)) +
            theme_bw() + theme(panel.grid = element_blank ()) +
            coord_cartesian (ylim = c(-0.5, 1)) + 
            geom_bar (aes(fill = Temp), stat = "identity", position = "dodge", width = .5) +
            geom_errorbar (aes(ymin = Score - SE, ymax = Score + SE, group = Cond), position = position_dodge(.9), width = .08) +
            labs(y = "Scores" , x = "Cond") +
            scale_y_continuous (breaks = pretty_breaks(n=8)) +
            theme(legend.title = element_blank()) +
            theme(legend.position = "right")

The alternative codes I have tried, which I couldn't get to work either, included adding "show.legend = FALSE" to geom_bar(); adding "facet_wrap(~Cond)" plot.a; and introducing "fill = Temp" within ggplot(aes()). The closest solution was when I changed the position_dodge() argument into:

geom_bar (aes(fill = Temp), stat = "identity", position = position_dodge(width = .5)) +
geom_errorbar (aes(ymin = Score - SE, ymax = Score + SE, group = Cond), position = position_dodge(.5), width = .08) +

(the rest of the code remains the same). This moved the error bars towards the center of the columns, yet also moved the columns towards each other, eventually making them overlap (see attached figure). see attached figure

I would very much appreciate help on this.

Thanks!

like image 599
Bahar Avatar asked Feb 16 '16 01:02

Bahar


People also ask

How do you add error bars to ggplot?

Start by initializing ggplot with the summary statistics data: Specify x and y as usually. Specify ymin = len-sd and ymax = len+sd to add lower and upper error bars. If you want only to add upper error bars but not the lower ones, use ymin = len (instead of len-sd ) and ymax = len+sd .

How do you plot error bars in R?

Error bars can be added to plots using the arrows() function and changing the arrow head. You can add vertical and horizontal error bars to any plot type. Simply provide the x and y coordinates, and whatever you are using for your error (e.g. standard deviation, standard error).

How do I increase the space between grouped bars in ggplot2?

How do I increase the space between grouped bars in ggplot2? For grouped bars, there is no space between bars within each group by default. However, you can add some space between bars within a group, by making the width smaller and setting the value for position_dodge to be larger than width.

How do you center error bars in Excel?

Click More Error Bar Options, and then under Vertical Error Bars or Horizontal Error Bars, click the display and error amount options that you want to use. Note: The direction of the error bars depends on the chart type of your chart. For scatter charts, both horizontal and vertical error bars are displayed by default.


2 Answers

Nice question. A couple of comments:

  1. In general, it's a good practice to set all your aesthetics in the original ggplot() call, and to override them with different aesthetics only if needed in the individual geom_xyz() calls. In your code, you were setting the fill aesthetic twice, once in ggplot and once in geom_bar. You also set the group aesthetic in geom_errorbar(). I don't think any of those things were the ultimate problem, but they did make it harder to debug your code.

  2. The main problem was that the width argument in geom_bar has to match the position_dodge() argument inside geom_errorbar. So if you have

    # ...
    geom_bar(stat = "identity", position = "dodge", width = 0.5)
    # ...
    

    Then you've got to make sure your geom_errorbar() looks like

    # ...
    geom_errorbar(width = .08, position = position_dodge(0.5)) 
    # ...
    

Putting it all together:

require(ggplot2)
require(scales)

# define data
a <- data.frame (Cond = c("In", "In", "Out", "Out"),
                Temp = c("Hot", "Cool", "Hot", "Cool"),
                Score = c(.03, -.15, 0.84, 0.25),
                SE = c(.02, .08, .14, .12))

# return plot with everything except error bars
a.bar <- ggplot (data = a, aes(x = Cond, 
                               y = Score, 
                               fill = Temp,
                               ymin = Score - SE,
                               ymax = Score + SE)) +
            theme_bw() + 
            theme(panel.grid = element_blank ()) +
            coord_cartesian(ylim = c(-0.5, 1)) + 
            # manually setting the width means we will have to tell geom_errorbar() about the new width
            geom_bar(stat = "identity", position = "dodge", width = 0.5) + 
            labs(y = "Scores", x = "Cond") +
            scale_y_continuous(breaks = pretty_breaks(n = 8)) +
            theme(legend.title = element_blank()) +
            theme(legend.position = "right")

# show plot w/ errorbars, note that argument to position_dodge is same as width supplied above
a.bar + geom_errorbar(width = .08, position = position_dodge(0.5)) 

# save results
ggsave('SO_35424162.png')

Final graph

like image 195
Curt F. Avatar answered Sep 29 '22 15:09

Curt F.


I would like to add, since I ran into the same issue:

It is very important to specify the fill parameter in the main aes() and not in the geom_barplot.

like image 23
Clément Goubert Avatar answered Sep 29 '22 14:09

Clément Goubert