R Tips

Home

Contact

Steven Holland

Adding error bars to a simple bar plot

22 January, 2013

Many things are easy in R are simple, but sometimes the solution is not obvious. Adding error bars to a bar plot is one of those things.

The segments() command lets you draw line segments, provided you specify the coordinates of the beginning and end of the segments. Since an error bar is just a line segment, the x coordinates for the start and the end are the center of the top of the bar, and the y coordinates are the top of the bar plus or minus the length of the error bar. I assumed that the centers of the bars would be integers, that is, if you had three bars, that their centers would be at 1, 2, and 3. That is not true - the centers of the bars are not integers, which makes finding their locations trickier.

You could use the locator() function to find the centers of the bars, but clicking on points can be imprecise. It is also impractical when there are many bars. The easy solution to finding the bar centers is in the barplot() command itself: in addition to plotting the graph, the function also returns a vector of the centers of each bar.

Here is how it all works. First, I will use the mean lengths of three small mammals, with the standard errors of those lengths.

names <- c("squirrel", "rabbit", "chipmunk") means <- c(23, 28, 19) standardErrors <- c(1.2, 1.7, 0.9)

Because the top of the plot is scaled to the tallest bar, the error bars will get clipped if I add them. To prevent this, I calculate the top of the highest bar; here, the error bars I am using are plus or minus two standard errors.

plotTop <- max(means+standardErrors*2)

First, I will plot the graph, with the bars filled with gray, with y-axis labels rotated (las=1), and with the limits on the y-axis expanded so they will include the error bars. I assign the barplot() command to barCenters, because the command returns a vector of the centers of the bars.

barCenters <- barplot(means, names.arg=names, col="gray", las=1, ylim=c(0,plotTop))

Finally, I add the error bars using segments(), where the x coordinates for the beginning and end of each bar are saved in barCenters. The y coordinate of the bottom of each bar is the mean minus two standard errors, and the y coordinate of the top of each bar is the mean plus two standard errors. To make the bars bolder, I double the line width (lwd=2).

segments(barCenters, means-standardErrors*2, barCenters, means+standardErrors*2, lwd=2)

Alternatively, if you prefer your error bars to have ticks at the end, use the arrows() command, setting code=3 to put ticks at both ends, and setting angle=90 to place the ticks at right angles to the main error bar.

arrows(barCenters, means-standardErrors*2, barCenters, means+standardErrors*2, lwd=2, angle=90, code=3)

Here is all the code, which can be pasted right into R to demonstrate the whole process:

means <- c(23, 28, 19) names <- c("squirrel", "rabbit", "chipmunk") standardErrors <- c(1.2, 1.7, 0.9) plotTop <- max(means+standardErrors*2) barCenters <- barplot(means, names.arg=names, col="gray", las=1, ylim=c(0,plotTop)) segments(barCenters, means-standardErrors*2, barCenters, means+standardErrors*2, lwd=2)

Pretty straightforward!