【问题标题】:How to merge legends for color and shape when geom_hline has a separate (additional) entry in the color legend?当 geom_hline 在颜色图例中有单独的(附加)条目时,如何合并颜色和形状的图例?
【发布时间】:2015-08-30 00:43:24
【问题描述】:

我有以下代码,它会产生以下情节:

cols <- brewer.pal(n = 3, name = 'Dark2')

p4 <- ggplot(all.m, aes(x=xval, y=yval, colour = Approach, ymax = 0.95)) + theme_bw() + 
  geom_errorbar(aes(ymin= yval - se, ymax = yval + se), width=5, position=pd) + 
  geom_line(position=pd) + 
  geom_point(aes(shape=Approach, colour = Approach), size = 4) + 
  geom_hline(aes(yintercept = cp.best$slope, colour = "C2P"), show_guide = FALSE) + 
  scale_color_manual(name="Approach", breaks=c("C2P", "P2P", "CP2P"), values =  cols[c(1,3,2)]) + 
  scale_y_continuous(breaks = seq(0.4, 0.95, 0.05), "Test AUROC") +
  scale_x_continuous(breaks = seq(10, 150, by = 20), "# Number of Patient Samples in Training")
p4 <- p4 + theme(legend.direction = 'horizontal', 
      legend.position = 'top', 
      plot.margin = unit(c(5.1, 7, 4.5, 3.5)/2, "lines"), 
      text = element_text(size=15), axis.title.x=element_text(vjust=-1.5), axis.title.y=element_text(vjust=2))   
p4 <- p4 + guides(colour=guide_legend(override.aes=list(shape=c(NA,17,16))))

p4

当我在geom_point 中尝试show_guide = FALSE 时,上图例中点的形状都设置为默认的实心圆。

如何使下图例消失,而不影响上图例?

【问题讨论】:

  • 您能否再描述一下您的数据和目标?这是正确的吗:您有 3 种方法(C2P、P2P 和 CP2P),其中 2 种方法(P2P、CP2P)的 y 值因 xval 而异。对于 C2P,yval 始终为 0.66。您想绘制 (1) P2P 和 CP2P 的线和点,(2) 仅用于 C2P 的线,以及 (3) 在一个框中显示所有三种方法的图例?

标签: r ggplot2 colors legend


【解决方案1】:

这是一个解决方案,包含可重复的数据:

library("ggplot2")
library("grid")
library("RColorBrewer")

cp2p <- data.frame(xval = 10 * 2:15, yval = cumsum(c(0.55, rnorm(13, 0.01, 0.005))), Approach = "CP2P", stringsAsFactors = FALSE)
p2p <- data.frame(xval = 10 * 1:15, yval = cumsum(c(0.7, rnorm(14, 0.01, 0.005))), Approach = "P2P", stringsAsFactors = FALSE)

pd <- position_dodge(0.1)
cp.best <- list(slope = 0.65)

all.m <- rbind(p2p, cp2p)
all.m$Approach <- factor(all.m$Approach, levels = c("C2P", "P2P", "CP2P"))
all.m$se <- rnorm(29, 0.1, 0.02)
all.m[nrow(all.m) + 1, ] <- all.m[nrow(all.m) + 1, ] # Creates a new row filled with NAs
all.m$Approach[nrow(all.m)] <- "C2P"
cols <- brewer.pal(n = 3, name = 'Dark2')

p4 <- ggplot(all.m, aes(x=xval, y=yval, colour = Approach, ymax = 0.95)) + theme_bw() + 
  geom_errorbar(aes(ymin= yval - se, ymax = yval + se), width=5, position=pd) + 
  geom_line(position=pd) + 
  geom_point(aes(shape=Approach, colour = Approach), size = 4, na.rm = TRUE) + 
  geom_hline(aes(yintercept = cp.best$slope, colour = "C2P")) + 
  scale_color_manual(values = c(C2P = cols[1], P2P = cols[2], CP2P = cols[3])) + 
  scale_shape_manual(values = c(C2P = NA, P2P = 16, CP2P = 17)) +
  scale_y_continuous(breaks = seq(0.4, 0.95, 0.05), "Test AUROC") +
  scale_x_continuous(breaks = seq(10, 150, by = 20), "# Number of Patient Samples in Training")
p4 <- p4 + theme(legend.direction = 'horizontal', 
                 legend.position = 'top', 
                 plot.margin = unit(c(5.1, 7, 4.5, 3.5)/2, "lines"), 
                 text = element_text(size=15), axis.title.x=element_text(vjust=-1.5), axis.title.y=element_text(vjust=2))   
p4

诀窍是确保all.m$Approach 的所有所需级别都出现在all.m 中,即使其中一个从图表中删除。 geom_pointna.rm = TRUE 参数抑制了有关省略点的警告。

【讨论】:

    【解决方案2】:

    简答:
    只需添加一个虚拟geom_point 层(透明点),其中shape 映射到与geom_hline 相同的level

    geom_point(aes(shape = "int"), alpha = 0) 
    

    更长的答案:
    只要有可能,ggplot 会合并/组合不同aesthetics 的图例。例如,如果colourshape 映射到同一个变量,则这两个图例合二为一。

    我使用简单的数据集来说明这一点,其中包含“x”、“y”和具有两个级别的分组变量“grp”:

    df <- data.frame(x = rep(1:2, 2), y = 1:4, grp = rep(c("a", "b"), each = 2))
    

    首先我们将colorshape 都映射到“grp”

    ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
      geom_line() +
      geom_point(size = 4)
    

    好的,aesthetics、colorshape 的图例合并为一个。

    然后我们添加一个geom_hline。我们希望它具有与geom_lines 不同的颜色以显示在图例中。因此,我们将color映射到一个变量,即将color 放在geom_hlineaes 中。在这种情况下,我们不会将颜色映射到数据集中的变量,而是映射到常量。我们可以给常量取一个想要的名字,这样以后我们就不需要重命名图例条目了。

    ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
      geom_line() +
      geom_point(size = 4) +
      geom_hline(aes(yintercept = 2.5, color = "int"))
    

    现在出现了两个图例,一个是geom_linegeom_hlinecolor aesthetics,一个是geom_points 的shape。原因是color映射到的“变量”现在包含三个层次:原始数据中的两个层次'grp',加上引入的层次'int'在geom_hlineaes。因此,color 刻度中的级别与shape 刻度中的级别不同,默认情况下 ggplot 无法将两个刻度合并为一个图例。

    如何结合这两个传说?

    一种可能性是通过使用具有透明点 (alpha = 0) 的虚拟 geom_point 层为 shape 引入与 color 相同的附加级别,以便两个aesthetics 包含相同的关卡:

    ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
      geom_line() +
      geom_point(size = 4) +
      geom_hline(aes(yintercept = 2.5, color = "int")) +
      geom_point(aes(shape = "int"), alpha = 0) # <~~~~ a blank geom_point
    

    另一种可能性是将原始分组变量转换为factor,并将“geom_hline 级别”添加到原始级别。然后在scale_shape_discrete 中使用drop = FALSE 来包含“未使用的因子级别”:

    datadf$grp <- factor(df$grp, levels = c(unique(df$grp), "int"))
    
    ggplot(data = df, aes(x = x, y = y, color = grp, shape = grp)) +
      geom_line() +
      geom_point(size = 4) +
      geom_hline(aes(yintercept = 2.5, color = "int")) +
      scale_shape_discrete(drop = FALSE)
    

    然后,如您所知,您可以使用guides 函数来“override”图例中的shapeaesthetics,并从geom_hline 条目中删除形状,方法是将其设置为NA:

    guides(colour = guide_legend(override.aes = list(shape = c(16, 17, NA))))
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-06-26
      • 2022-11-27
      • 2014-05-18
      • 1970-01-01
      • 1970-01-01
      • 2013-06-14
      • 2015-08-19
      • 2020-02-26
      相关资源
      最近更新 更多