两个geom_points添加一个图例

Posted

技术标签:

【中文标题】两个geom_points添加一个图例【英文标题】:Two geom_points add a legend 【发布时间】:2013-07-16 20:09:55 【问题描述】:

我用以下代码绘制了一个 2 geom_point 图:

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(ggplot2)
ggplot() +
  geom_point(aes(x = year,y = boys),data=arbuthnot,colour = '#3399ff') +
  geom_point(aes(x = year,y = girls),data=arbuthnot,shape = 17,colour = '#ff00ff') +
  xlab(label = 'Year') +
  ylab(label = 'Rate')

我只是想知道如何在右侧添加图例。具有相同的形状和颜色。三角形粉色应该有“女人”的传说,蓝色圆圈应该有“男人”的传说。看起来很简单,但经过多次试验我做不到。 (我是 ggplot 的初学者)。

【问题讨论】:

【参考方案1】:

这是我通常使用的技巧。将 colour 参数添加到 aes 并将其用作标签名称的指示符。

ggplot() +
  geom_point(aes(x = year,y = boys, colour = 'Boys'),data=arbuthnot) +
  geom_point(aes(x = year,y = girls, colour = 'Girls'),data=arbuthnot,shape = 17) +
  xlab(label = 'Year') +
  ylab(label = 'Rate')

【讨论】:

好主意:-),知道如何为此指定颜色吗?我还在另一个 geom_point 中使用了啤酒调色板 scale_colour_discrete 【参考方案2】:

这是基于tidyverse 包的答案。可以使用管道%>% 将功能链接在一起。以一种连续的方式创建绘图,无需创建临时变量。更多关于管道的信息可以在这篇文章中找到What does %>% function mean in R?

据我所知,ggplot2 中的图例仅基于审美变量。因此,要添加离散图例,请使用类别列,并根据类别更改美学。例如,在 ggplot 中,这是由 aes(color=category) 完成的。

因此,要将数据框的两个(或更多)不同变量添加到图例中,需要转换数据框,以便我们有一个类别列告诉我们正在绘制哪一列(变量),以及第二列实际上持有价值。 tidyr::gather 函数也由tidyverse 加载,正是这样做的。

然后通过指定哪些美学变量需要不同来创建图例。在此示例中,代码如下所示:

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(tidyverse)

arbuthnot %>%
    rename(Year=year,Men=boys,Women=girls) %>%
    gather(Men,Women,key = "Sex",value = "Rate") %>%
    ggplot() +
    geom_point(aes(x = Year, y=Rate, color=Sex, shape=Sex)) +
    scale_color_manual(values = c("Men" = "#3399ff","Women"= "#ff00ff")) +
    scale_shape_manual(values = c("Men" = 16, "Women" =  17))

请注意,tidyverse 包也会自动加载到 ggplot2 包中。可以在他们的网站tidyverse.org 上找到已安装软件包的概述。

在上面的代码中,我还使用了函数dplyr::rename(也由tidyverse 加载)首先将列重命名为所需的标签。由于图例自动采用与类别名称相同的标签。

还有第二种重命名图例标签的方法,即通过labels = 参数在scale_aesthetic_manual 函数中明确指定标签。示例参见legends cookbook。但不推荐,因为它会随着更多变量而迅速变得混乱。

【讨论】:

【参考方案3】:

这是一种不使用 reshape::melt 的方法。 reshape::melt 有效,但如果你想在图中添加其他东西,比如线段,你可以进入绑定。下面的代码使用原始的数据组织。修改图例的关键是确保 scale_color_manual(...) 和 scale_shape_manual(...) 的参数相同,否则您将得到两个图例。

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(ggplot2)
library(reshape2)



ptheme <- theme (
  axis.text            = element_text(size = 9),              # tick labels
  axis.title           = element_text(size = 9),              # axis labels
  axis.ticks           = element_line(colour = "grey70", size = 0.25),
  panel.background     = element_rect(fill = "white", colour = NA),
  panel.border         = element_rect(fill = NA, colour = "grey70", size = 0.25),
  panel.grid.major     = element_line(colour = "grey85", size = 0.25),
  panel.grid.minor     = element_line(colour = "grey93", size = 0.125),
  panel.margin         = unit(0 , "lines"),
  legend.justification = c(1, 0), 
  legend.position      = c(1, 0.1),
  legend.text          = element_text(size = 8),
  plot.margin          = unit(c(0.1, 0.1, 0.1, 0.01), "npc")   # c(bottom, left, top, right), values can be negative
)

cols    <- c( "c1" = "#ff00ff", "c2" = "#3399ff" )
shapes  <- c("s1" = 16, "s2" = 17)

p1 <- ggplot(data = arbuthnot, aes(x = year))
p1 <- p1 + geom_point(aes( y = boys,  color = "c1", shape = "s1"))
p1 <- p1 + geom_point(aes( y = girls, color = "c2", shape = "s2")) 
p1 <- p1 + labs( x = "Year", y = "Rate" )
p1 <- p1 + scale_color_manual(name = "Sex", 
                                breaks = c("c1", "c2"), 
                                values = cols,
                                labels = c("boys", "girls"))
p1 <- p1 + scale_shape_manual(name = "Sex", 
                              breaks = c("s1", "s2"),
                              values = shapes,
                              labels = c("boys", "girls"))
p1 <- p1 +  ptheme

print(p1)

output results

【讨论】:

如果我们有 5-6 种以上的水果,而不是“男孩”和“女孩”,那么这段代码很快就会变得混乱。 干得好,你节省了我一些时间。谢谢你肯垃圾【参考方案4】:

如果你重命名原始数据框的列,然后用reshape2::melt将其融合为长格式,在ggplot2中处理起来会容易得多。通过在 ggplot 命令中指定 colorshape 美学,并手动指定颜色和形状的比例,将出现图例。

source("http://www.openintro.org/stat/data/arbuthnot.R")
library(ggplot2)
library(reshape2)

names(arbuthnot) <- c("Year", "Men", "Women")

arbuthnot.melt <- melt(arbuthnot, id.vars = 'Year', variable.name = 'Sex', 
    value.name = 'Rate')

ggplot(arbuthnot.melt, aes(x = Year, y = Rate, shape = Sex, color = Sex))+
geom_point() + scale_color_manual(values = c("Women" = '#ff00ff','Men' = '#3399ff')) + 
scale_shape_manual(values = c('Women' = 17, 'Men' = 16))

【讨论】:

谢谢正是我想要的。该结构似乎比仅使用 ggplot2 更难获得。我会看看 reshape2 文档...谢谢

以上是关于两个geom_points添加一个图例的主要内容,如果未能解决你的问题,请参考以下文章

你如何使geom_points透明化

在 geom_boxplot 上覆盖 geom_point(aes(shape))?

包含包含表达式的图例文本

用ggplot2添加图例[重复]

在ggplot的图例中设置最小/最大尺寸

R中ggplot2中多个图例的图例键之间的间距