rplot

using arrows function with matplot in R


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.


Solution

  • 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