Exclude arrowheads in legend entry on ggplot2

2019-05-09 22:56发布

问题:

I'm drawing a geom_path() and I'd like it to have arrows in the plot, but not have arrows in the legend. Googling around suggests that something of the form

guides(color=guide_legend(override.aes = list(..)) 

will have the answer, but I can't find documentation of what that list() expects. The help file for guide_legend() says to "look at the examples" to learn more about override.aes but there is only one example showing how to set the alpha level in the legend.

To make what I'd like to do concrete, here's code that produces a plot with arrowheads,

data <- data.frame(x=c(1, 1, 1, 2),
                   y=c(1, 2, 1, 1),
                   color=c('color1', 'color1', 'color2', 'color2'))

library(ggplot2)
ggplot(data, aes(x=x, y=y, color=color, group=color)) +
  geom_path(size=2,
            arrow = arrow(angle = 30, 
                          length = unit(0.1, "inches"),
                          ends = "last", type = "closed")) +
  theme_bw()

This outputs

But what I'm looking for is the legend with the not arrowhead version, as in

ggplot(data, aes(x=x, y=y, color=color, group=color)) +
  geom_path(size=2) +
  theme_bw()

Thank you!

回答1:

In theory, this should work:

ggplot(data, aes(x=x, y=y, color=color, group=color)) +
  geom_path(size=2,
            arrow = arrow(angle = 30, 
                          length = unit(0.1, "inches"),
                          ends = "last", type = "open")) +
  theme_bw() +
  guides(color=guide_legend(override.aes = list(arrow = NULL))) 

However, it doesn't.

The alternative is to give GeomPath a new legend-drawing function that doesn't draw an arrow:

# legend drawing function that ignores arrow setting
# modified from ggplot2 function `draw_key_path`,
# available here: https://github.com/tidyverse/ggplot2/blob/884fdcbaefd60456978f19dd2727ab698a07df5e/R/legend-draw.r#L108
draw_key_line <- function(data, params, size) {
  data$linetype[is.na(data$linetype)] <- 0

  grid::segmentsGrob(0.1, 0.5, 0.9, 0.5,
    gp = grid::gpar(
      col = alpha(data$colour, data$alpha),
      lwd = data$size * .pt,
      lty = data$linetype,
      lineend = "butt"
    )
  )
}

# override legend drawing function for GeomPath
GeomPath$draw_key <- draw_key_line

ggplot(data, aes(x=x, y=y, color=color, group=color)) +
  geom_path(size=2,
            arrow = arrow(angle = 30, 
                          length = unit(0.1, "inches"),
                          ends = "last", type = "closed")) +
  theme_bw()

Note that this changes GeomPath for the remainder of your R session. To revert back to the original behavior, you can set:

GeomPath$draw_key <- draw_key_path


回答2:

One slightly hacky way to do this is simply to use the legend created by geom_line rather than the arrowhead one. Here I call geom_path with show.legend = FALSE to hide the arrowhead legend. Then I use geom_line, which just plots lines on top of the existing lines (so the plot doesn't change) but gives us a legend without arrowheads.

library(tidyverse)
data = tibble(x=c(1, 1, 1, 2),
                  y=c(1, 2, 1, 1),
                  color=c('color1', 'color1', 'color2', 'color2'))

ggplot(data, aes(x=x, y=y, color=color, group=color)) +
  geom_path(
    size=2,
    arrow = arrow(
      angle = 30,
      length = unit(0.1, "inches"),
      ends = "last", type = "closed"
    ),
    show.legend = FALSE
  ) +
  geom_line(size = 2) +
  theme_bw()



标签: r ggplot2