Search code examples
rplotarrows

Placing arrow heads to the middle of the lines in R


I have a plot where I draw arrows from points to points. I would like to put this arrow heads not to the end of the line, but to middle. Is there a simple way to do it other than placing extra arrows with half length of the according line? My code is this:

plot(x, y, xlim=range(x), ylim=range(y), xlab="x", ylab="y", pch=16,
     main="Filled Plane")

for(i in 1:20){
  arrows(x[i], y[i], x[i+1], y[i+1], length = 0.25, angle = 30, col = i)
}

Solution

  • Make a custom function myArrow() and add one new argument cut to control the proportion of the arrows

    myArrow <- function(x0, y0, x1, y1, cut = 1, ...){
      x.new <- (1 - cut) * x0 + cut * x1
      y.new <- (1 - cut) * y0 + cut * y1
      # segments(x0, y0, x1, y1, ...)
      arrows(x0, y0, x.new, y.new, ...)
    }
    

    Note1 : The computation of x.new and y.new in this custom function uses a simple mathematical concept, i.e. the Section Formula. The value of cut must be between 0 to 1.

    Note2 : The use of this function is equivalent to that of the original functionarrows() other than that it has one more new argument cut.

    Note3 : If you want complete lines behind the arrows, just remove the hash(#) in the function.


    Plot and try different cut value. For example, I use cut = 0.7. (If you want the arrowheads to the middle, use cut = 0.5.)

    # Toy Data
    x <- seq(1, 5.5, by = 0.5)
    y <- rep(c(1, 5), 5)
    
    plot(x, y, pch = 16)
    for(i in 1:9){
      myArrow(x[i], y[i], x[i+1], y[i+1], cut = 0.7, col = i, lwd = 2)
    }
    

    enter image description here