ggplot2 cross effect on legend

2019-07-21 08:00发布

I'm trying to plot two normal distributions and two vlines indicating the means. When I do so with ggplot2, the legend becomes a cross, making it hard to see that one of them is a dashed line.

ggplot(data = data.frame(x = c(-1, 6)), aes(x)) +
  stat_function(fun = dnorm, n = 100, args = list(mean = 2, sd = 1), aes(linetype = "a")) +
  stat_function(fun = dnorm, n = 100, args = list(mean = 3, sd = 1), aes(linetype = "b")) +
  scale_linetype_manual("Density Function", values = c(1, 2)) +
  labs(x = "Value", y = "Probability Density") +
  geom_vline(aes(xintercept = 2, colour = "mean1"), show.legend = TRUE) +
  geom_vline(aes(xintercept = 3, colour = "mean2"), show.legend = TRUE, linetype = 2) +
  scale_colour_manual("Mean", values = c(mean1 = "#F8766D", mean2 = "#C77CFF"), 
                      labels = c("Mean a", "Mean b")) +
  ggtitle("Legend Help")

标签: r ggplot2 legend
2条回答
戒情不戒烟
2楼-- · 2019-07-21 08:22

This discussion on GitHub looks like it was addressing a similar issue.

The fix that Hadley recommended was to call show.legend = NA

I reproduced your plot doing this (full code below), and the issue went away:

ggplot(data = data.frame(x = c(-1, 6)), aes(x)) +
stat_function(fun = dnorm, n = 100, args = list(mean = 2, sd = 1), aes(linetype = "a")) +
stat_function(fun = dnorm, n = 100, args = list(mean = 3, sd = 1), aes(linetype = "b")) +
scale_linetype_manual("Density Function", values = c(1, 2)) +
labs(x = "Value", y = "Probability Density") +
geom_vline(aes(xintercept = 2, colour = "mean1"), show.legend = NA) +
geom_vline(aes(xintercept = 3, colour = "mean2"), show.legend = NA, linetype = 2) +
scale_colour_manual("Mean", values = c(mean1 = "#F8766D", mean2 = "#C77CFF"), 
                  labels = c("Mean a", "Mean b")) +
ggtitle("Legend Help")

enter image description here

查看更多
爱情/是我丢掉的垃圾
3楼-- · 2019-07-21 08:25
ggplot(data = data.frame(x = c(-1, 6)), aes(x)) +
  stat_function(
    fun = dnorm, n = 100, args = list(mean = 2, sd = 1), aes(linetype = "a")
  ) +
  stat_function(
    fun = dnorm, n = 100, args = list(mean = 3, sd = 1), aes(linetype = "b")
  ) +
  geom_vline(
    data = data.frame(
      xintercept = c(2, 3), colour = c("mean1", "mean2"),
      stringsAsFactors = FALSE
    ),
    aes(xintercept = xintercept, colour = colour)
  ) +
  scale_colour_manual(
    name = "Mean", 
    values = c(mean1 = "#F8766D", mean2 = "#C77CFF"), 
    labels = c("Mean a", "Mean b")
  ) +
  scale_linetype_manual("Density Function", values = c(1, 2)) +
  labs(
    x = "Value", y = "Probability Density", title = "Legend Help"
  ) 

enter image description here

show.legend=TRUE was forcing inheritance across all line aesthetics. Leaving it NA removes the inheritance and the fact that you used mapped aesthetics for the vline (which I modified a bit) means you get the extra vline legend for free anyway.

查看更多
登录 后发表回答