Home > OS >  How to show arrows in backward and forward directions in a ggplot2 legend?
How to show arrows in backward and forward directions in a ggplot2 legend?

Time:06-24

I have a dataframe with coordinates of arrows:

arrows = data.frame(direction = factor(c("forward", "backward", "backward")),
                x = c(0, 0, 0),
                xend = c(1, 1, 1),
                y = c(1, 1.2, 1.1),
                yend = c(1, 1.2, 1.1))

I want to use this data to plot arrows - some goes in the forward direction and vice versa.

So far I tried:

library(ggplot2)

ggplot()  
        geom_segment(data = arrows, 
                     aes(x, y, xend = xend, yend = yend, col = direction),
                     arrow = arrow(length = unit(0.3, "cm"), type = "closed", ends = c("last", "first")))

which produces:

enter image description here

There are 2 problems I want to solve in this plot:

  1. How can I make sure that ggplot 'understands' which plot is "forward" and "backward", so it gives them the right legend?

  2. How to change the legend so that it shows forward direction with an arrow that goes forward, and the backward arrow that goes backward?

CodePudding user response:

How about mapping the "direction" to "first" and "last" directly, e.g.

ggplot()  
  geom_segment(data = arrows, 
                 aes(x = x, xend = xend, y = y, yend = yend, col = direction),
               arrow = arrow(length = unit(0.3, "cm"), type = "closed", ends = ifelse(arrows$direction == "forward", "first", "last" )))  
  scale_colour_manual(values = c("darkred", "darkblue"), labels = c("forward", "backward"))

I'd also used a scale_colour_manual to control which direction is forward and which backward.

Another question on SO asked about custom glyphs in legends - show filled arrow in legend ggplot - This should allow the different arrow direction, but might not be worth the effort.

CodePudding user response:

The ends argument needs to be set for each arrow, yours is only length two so tha last arrow will be the wrong direction since it is using the default which is "last" but since the arrow goes backwards it should be "first"

arrows <- data.frame(direction = (c("forward", "backward", "backward")),
                    x = c(0, 0, 0),
                    xend = c(1, 1, 1),
                    y = c(1, 1.2, 1.1),
                    yend = c(1, 1.2, 1.1))

arrow_head <- function(direction) {
  if(direction == "backward") {
    return("first")
  } else {
    return("last")
  }
}

ggplot()  
  geom_segment(data = arrows,
               aes(x, y, xend = xend, yend = yend, col = direction),
               arrow = arrow(length = unit(0.3, "cm"), type = "closed", ends = lapply(arrows$direction, arrow_head)))
  • Related