用垂直线和正确的图例绘制两个密度

时间:2018-06-05 11:04:50

标签: r ggplot2

我想绘制两个密度,两条垂直线用于平均值。 传说曾经是表示密度,一旦表示垂直 线。

我尝试了下面的代码。但是,只显示一个图例,标签错误。

任何人都可以帮助我吗?

set.seed(1234)
data <- data.frame(value = rnorm(n = 10000, mean = 50, sd = 20),
                   type  = sample(letters[1:2], size = 10000, replace = TRUE))

data$value[data$type == "b"] <- data$value[data$type == "b"] + 50

mean.a <- mean(data$value[data$type == "a"])
mean.b <- mean(data$value[data$type == "b"])

library(ggplot2)

gp <- ggplot(data = data, aes(x = value))

gp <- gp + geom_density(aes(fill = type), color = "black", alpha=0.3, lwd = 1.0, show.legend = TRUE)
gp <- gp + scale_fill_manual(breaks = 1:2, name = "Density", values = c("a" = "green", "b" = "blue"), labels = c("a" = "Density a", "b" = "Density b") )

gp <- gp + geom_vline(aes(color="mean.a", xintercept=mean.a), linetype="solid",  size=1.0, show.legend = NA)
gp <- gp + geom_vline(aes(color="mean.b", xintercept=mean.b), linetype="dashed", size=1.0, show.legend = NA)
gp <- gp + scale_color_manual(name = "", values = c("mean.a" = "red", "mean.b" = "darkblue"), labels = c("mean.a" = "Mean.A", "mean.b" = "Mean.B"))

gp <- gp + theme(legend.position="top")

gp

Density plot with vertical lines but wrong legend

1 个答案:

答案 0 :(得分:0)

以下是几种方法。我不确定,但我认为有一些困难来自于拥有多个geom_vline并试图在aes中对代码进行硬编码。您可以在此处构建三个比例:填充密度曲线,以及垂直线的颜色和线型。但对于两个传说,你的目的是纠正我(如果我是误读的话)。

处理获取正确传说的最简单方法是为均值制作一个小数据框,而不是每个均值的单个值。您可以使用dplyr轻松完成此操作,以计算每种类型的均值。

library(tidyverse)

set.seed(1234)
data <- data.frame(value = rnorm(n = 10000, mean = 50, sd = 20),
                   type  = sample(letters[1:2], size = 10000, replace = TRUE))

data$value[data$type == "b"] <- data$value[data$type == "b"] + 50

means <- group_by(data, type) %>% 
  summarise(mean = mean(value))

means
#> # A tibble: 2 x 2
#>   type   mean
#>   <fct> <dbl>
#> 1 a      50.3
#> 2 b      99.9

然后,当您进行绘图时,您可以进行一次geom_vline调用,分配means数据框,并根据此数据调整您想要的美学颜色和线型。然后诀窍是协调名称和标签:如果你没有为颜色和线型刻度设置相同的图例名称和标签,那么你就会有两个线条的图例。将它们设置为相同,您将获得平均线的单个图例。

ggplot(data, aes(x = value)) +
  geom_density(aes(fill = type), alpha = 0.3) +
  geom_vline(aes(xintercept = mean, color = type, linetype = type), data = means) +
  scale_color_manual(values = c("red", "darkblue"), labels = c("Mean.A", "Mean.B"), name = NULL) +
  scale_linetype_discrete(labels = c("Mean.A", "Mean.B"), name = NULL) +
  scale_fill_manual(values = c(a = "green", b = "blue"), name = "Density") 

第二种方法是添加一个步骤来创建平均数据框,您可以按照以后的方式标记类型,即&#34; Mean.A&#34;而不只是&#34; a&#34;。然后,您不需要调整标签,并且可以跳过线型比例 - 除非您想手动更改线型 - 然后只需删除labs中颜色和线型的图例名称。

means2 <- group_by(data, type) %>% 
  summarise(mean = mean(value)) %>%
  mutate(type = paste("Mean", str_to_upper(type), sep = "."))

means2
#> # A tibble: 2 x 2
#>   type    mean
#>   <chr>  <dbl>
#> 1 Mean.A  50.3
#> 2 Mean.B  99.9

ggplot(data, aes(x = value)) +
  geom_density(aes(fill = type), alpha = 0.3) +
  geom_vline(aes(xintercept = mean, color = type, linetype = type), data = means2) +
  scale_color_manual(values = c(Mean.A = "red", Mean.B = "darkblue")) +
  scale_fill_manual(values = c(a = "green", b = "blue"), name = "Density") +
  labs(color = NULL, linetype = NULL)

reprex package(v0.2.0)创建于2018-06-05。