做双图例时如何添加条件语句

Posted

技术标签:

【中文标题】做双图例时如何添加条件语句【英文标题】:how to add conditional statement when doing double legend 【发布时间】:2022-01-14 12:07:59 【问题描述】:

我尝试为水平线和垂直线制作带有图例的图。现在我想测试一下是否可以根据事件状态添加if语句。

对于带有DelaySickdf,我的代码有效。但是如果我想修改我的绘图部分,以便我可以在可能只有DelaySickdf 上使用它,我应该用我的geom_vlinescale_linetype_manualpart 做什么?例如,如果我想在 df2 上使用我的代码。


df<-structure(list(Day = c(0L, 0L, 0L, 1L, 1L, 1L, 8L, 8L, 8L, 15L, 
15L, 15L, 22L, 22L, 22L, 27L, 29L, 29L, 29L, 36L, 36L, 36L, 43L, 
43L, 43L, 43L, 43L, 43L), Subject = c("ELA", "Math", "Art", "Math", 
"Art", "ELA", "ELA", "Math", "Art", "ELA", "Math", "Art", "ELA", 
"Math", "Art", NA, "ELA", "Math", "Art", "ELA", "Math", "Art", 
"Art", "Art", "Math", "Math", "ELA", "ELA"), Score = c(73L, 157L, 
75L, 111L, 82L, 69L, 78L, 131L, 93L, 58L, 109L, 99L, 79L, 131L, 
84L, NA, 67L, 106L, 90L, 75L, 123L, 95L, 122L, 122L, 137L, 137L, 
83L, 83L), Event = c(NA, NA, NA, "Delay", "Delay", "Delay", NA, 
NA, NA, NA, NA, NA, NA, NA, NA, "Sick", NA, NA, NA, NA, NA, NA, 
"Sick", "Delay", "Sick", "Delay", "Sick", "Delay")), class = "data.frame", row.names = c(NA, 
-28L))

ggplot(data =df)+
    geom_line(data=df[!is.na(df$Score),],aes(x = Day, y = Score, color=Subject),size=0.8)+
        scale_colour_manual(breaks = c("ELA", "Math", "Art"),
                        values=c(ELA="#cc0022",Math="#70ad47", Art="#fd9300"))+
    geom_vline(data=df[(!is.na(df$Event)&df$Event=="Delay"),], aes(xintercept=jitter(Day), linetype="Delay"), color="black", size=0.4)+
geom_vline(data=df[(!is.na(df$Event)&df$Event=="Sick"),], aes(xintercept=jitter(Day), linetype="Sick"), color="purple", size=0.4)+
scale_linetype_manual(name = 'Event',
                        values = c('Delay' = 1,
                                   'Sick' = 1),
                        guide = guide_legend(override.aes = list(colour = c("black",
                        "purple"))))

df2 <-structure(list(Day = c(0L, 0L, 0L, 1L, 1L, 1L, 8L, 8L, 8L, 15L, 
15L, 15L, 22L, 22L, 22L, 27L, 29L, 29L, 29L, 36L, 36L, 36L, 43L, 
43L, 43L, 43L, 43L, 43L), Subject = c("ELA", "Math", "Art", "Math", 
"Art", "ELA", "ELA", "Math", "Art", "ELA", "Math", "Art", "ELA", 
"Math", "Art", NA, "ELA", "Math", "Art", "ELA", "Math", "Art", 
"Art", "Art", "Math", "Math", "ELA", "ELA"), Score = c(73L, 157L, 
75L, 111L, 82L, 69L, 78L, 131L, 93L, 58L, 109L, 99L, 79L, 131L, 
84L, NA, 67L, 106L, 90L, 75L, 123L, 95L, 122L, 122L, 137L, 137L, 
83L, 83L), Event = c(NA, NA, NA, "Delay", "Delay", "Delay", NA, 
NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, NA, 
NA, NA, NA, "Delay", NA, "Delay")), class = "data.frame", row.names = c(NA, 
-28L))

我正在考虑使用这样的东西(它们不起作用)

df<-df2
ggplot(data =df)+
    geom_line(data=df[!is.na(df$Score),],aes(x = Day, y = Score, color=Subject),size=0.8)+
        scale_colour_manual(breaks = c("ELA", "Math", "Art"),
                        values=c(ELA="#cc0022",Math="#70ad47", Art="#fd9300"))+
   if (grepl("Delay", df$Event)) geom_vline(data=df[(!is.na(df$Event)&df$Event=="Delay"),], aes(xintercept=jitter(Day), linetype="Delay"), color="black", size=0.4)+
   if (grepl("Sick", df$Event)) geom_vline(data=df[(!is.na(df$Event)&df$Event=="Sick"),], aes(xintercept=jitter(Day), linetype="Sick"), color="purple", size=0.4)+
scale_linetype_manual(name = 'Event',
                        values = c('Delay' = 1,
                                   'Sick' = 1),
                        guide = guide_legend(override.aes = list(colour = c("black",
                        "purple"))))

代码块 3:

ggplot(data =df)+
    geom_line(data=df[!is.na(df$Score),],aes(x = Day, y = Score, color=Subject),size=0.8)+
        scale_colour_manual(breaks = c("ELA", "Math", "Art"),
                        values=c(ELA="#cc0022",Math="#70ad47", Art="#fd9300"))+
 geom_vline(data=df[(!is.na(df$Event)&df$Event=="Delay"),], aes(xintercept=jitter(Day),linetype="Delay"), color="black", size=0.4)+
# geom_vline(data=df[(!is.na(df$Event)&df$Event=="Sick"),], aes(xintercept=jitter(Day) ), color="purple", size=0.4)+
scale_linetype_manual(name = 'Event',
                      values = c(
        "Delay" = 1,
        "Sick" = 1
      ),
                        guide = guide_legend(override.aes = list(colour = c("black",
                        "purple"))))

【问题讨论】:

【参考方案1】:

使用if 添加您在正确轨道上的图层。与其将条件单独放在 ggplot 代码中,我更喜欢在 ggplot 代码之外设置条件层,最好将所有内容都放在函数中。

这样做,实现所需结果的一个选项可能如下所示:

编辑 此外,您可以使用ggnewscale 包添加第二个颜色图例,而不是通过linetype aes 使用hack 来获得单独的图例。一个好处是我们不需要通过override.aes 摆弄,也不需要额外的条件来管理不同的情况:

library(ggplot2)

plot_fun <- function(df) 
  is_delay <- !is.na(df$Event) & df$Event == "Delay"
  is_sick <- !is.na(df$Event) & df$Event == "Sick"
  
  layer_delay <- if (any(is_delay)) geom_vline(data = df[is_delay, ], aes(xintercept = jitter(Day), color = "Delay"), size = 0.4)
  layer_sick <- if (any(is_sick)) geom_vline(data = df[is_sick, ], aes(xintercept = jitter(Day), color = "Sick"), size = 0.4)
  
  ggplot(data = df) +
    geom_line(data = df[!is.na(df$Score), ], aes(x = Day, y = Score, color = Subject), size = 0.8) +
    scale_colour_manual(
      breaks = c("ELA", "Math", "Art"),
      values = c(ELA = "#cc0022", Math = "#70ad47", Art = "#fd9300"),
    ) +
    ggnewscale::new_scale_color() +
    layer_delay +
    layer_sick +
    scale_colour_manual(
      name = "Event",
      values = c(Delay = "black", Sick = "purple"),
      limits = force
    )


plot_fun(df2)

【讨论】:

对于scale_linetype_manual( name = "Event", values = c( "Delay" = 1, "Sick" = 1 ), guide = guide_legend(override.aes = list(colour = c( "black", "purple" )),当我们只有一种类型的事件时,我们可以有这个传说事件是否正确?我在代码块 3(刚刚添加)之类的东西上尝试过,没有看到垂直线的图例 哈哈。你接受的速度比我意识到你的问题有第二部分要快。我刚刚进行了编辑,向您展示了一种处理指南的方法。 绝妙的方法!学到了很多:D 如果我正确理解您想要实现的目标,那么 theme(legend.box = "vertical") 可能就是您要寻找的。​​span> 哈哈。这是 24 小时内第三次被问到这个问题。您可以通过guide_xxxorder 参数设置图例的顺序,例如你可以做scale_xxx_yyy(..., guide = guide_legend(order = 1)) 让比例/图例出现在顶部,... = 2 第二个等等。根据文档,如果未设置顺序,ggplot2 将通过“...秘密算法”(:(请参阅 ?guide_legend)进行选择。有关不可预测性的更多信息,请参阅***.com/a/70293016/12993861。

以上是关于做双图例时如何添加条件语句的主要内容,如果未能解决你的问题,请参考以下文章

如何根据条件语句添加 React 组件,基于可变计数器评估布尔值

如何基于 Python If 语句添加条件 CSS 类

SQL Server - 条件语句的查询执行计划

sql语句中如何一个字段对查询出的多个值添加判断条件

如何在 PowerShell 中使用条件语句重命名文件

如何在php中的if语句中添加多个条件