sherlock85 sherlock85 - 5 months ago 38
R Question

Scatter plot with error bars

How can I generate the following plot in R? Points, shown in the plot are the averages, and their ranges correspond to minimal and maximal values.
I have data in two files (below is an example).

x y
1 0.8773
1 0.8722
1 0.8816
1 0.8834
1 0.8759
1 0.8890
1 0.8727
2 0.9047
2 0.9062
2 0.8998
2 0.9044
2 0.8960
.. ...

enter image description here


First of all: it is very unfortunate and surprising that R cannot draw error bars "out of the box".

Here is my favourite workaround, the advantage is that you do not need any extra packages. The trick is to draw arrows (!) but with little horizontal bars instead of arrowheads (!!!). This not-so-straightforward idea comes from the R Wiki Tips and is reproduced here as a worked-out example.

Let's assume you have a vector of "average values" avg and another vector of "standard deviations" sdev, they are of the same length n. Let's make the abscissa just the number of these "measurements", so x <- 1:n. Using these, here come the plotting commands:

plot(x, avg,
    ylim=range(c(avg-sdev, avg+sdev)),
    pch=19, xlab="Measurements", ylab="Mean +/- SD",
    main="Scatter plot with error bars"
# hack: we draw arrows but with very special "arrowheads"
arrows(x, avg-sdev, x, avg+sdev, length=0.05, angle=90, code=3)

The result looks like this:

example scatter plot with error bars

In the arrows(...) function length=0.05 is the size of the "arrowhead" in inches, angle=90 specifies that the "arrowhead" is perpendicular to the shaft of the arrow, and the particularly intuitive code=3 parameter specifies that we want to draw an arrowhead on both ends of the arrow.

For horizontal error bars the following changes are necessary, assuming that the sdev vector now contains the errors in the x values and the y values are the ordinates:

plot(x, y,
    xlim=range(c(x-sdev, x+sdev)),
# horizontal error bars
arrows(x-sdev, y, x+sdev, y, length=0.05, angle=90, code=3)