I've been using the arrows
function (as suggested in Scatter plot with error bars ) to create error bars around each point of a scatterplot.
However, rather than plot()
, I'm using the matplot()
to simultaneously plot several scatterplots on the same figure. However, the arrows
function needs to be called individually for each dependent variable plotted, e.g. for a contrived example where se_mat
scales with x
:
x=1:10
ymat = cbind(A=1.5*x, B=2*x, C=3*x)
se_mat = cbind(.05*x, .1*x, .15*x)
matplot(x, ymat, col=1:3, pch=19, type="o")
arrows(x, ymat[,1]-se_mat[,1],x,ymat[,1]+se_mat[,1],code=3,angle=90,length=.05)
arrows(x, ymat[,2]-se_mat[,2],x,ymat[,2]+se_mat[,2],code=3,angle=90,length=.05)
arrows(x, ymat[,3]-se_mat[,3],x,ymat[,3]+se_mat[,3],code=3,angle=90,length=.05)
Is there a more efficient way to do this, analogous to the use of matplot()
rather than plot()
that would work for arrows()
? In this example, it isn't a big deal because I only have 3 y
-vectors collected in a matrix
, but it's an issue for larger data sets.
Many R functions are vectorized, including arrows
.
The code below works because matrices are stored in column-major order, so the subtract/add standard errors respect that order. There is no need to separate the code by columns.
(In case of doubt, it's many times better to give it a try.)
x <- 1:10
ymat <- cbind(1.5*x, 2*x, 3*x)
colnames(ymat) <- c("A","B","C")
se_mat <- cbind(0.05*x, 0.1*x, 0.15*x)
matplot(x, ymat, col=1:3, pch=19, type = "o")
arrows(x, ymat - se_mat, x, ymat + se_mat, code = 3, angle = 90, length = 0.05)
Created on 2025-06-05 with reprex v2.1.1