Exclude arrowheads in legend entry on ggplot2

2019-05-09 23:11发布

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 Plot with arrowheads

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()

enter image description here

Thank you!

标签: r ggplot2
2条回答
聊天终结者
2楼-- · 2019-05-09 23:37

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()

enter image description here

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
查看更多
女痞
3楼-- · 2019-05-09 23:37

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()

查看更多
登录 后发表回答