ggplot2 cross effect on legend

2019-07-21 08:17发布

问题:

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

回答1:

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

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.



回答2:

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



标签: r ggplot2 legend