做双图例时如何添加条件语句
Posted
技术标签:
【中文标题】做双图例时如何添加条件语句【英文标题】:how to add conditional statement when doing double legend 【发布时间】:2022-01-14 12:07:59 【问题描述】:我尝试为水平线和垂直线制作带有图例的图。现在我想测试一下是否可以根据事件状态添加if
语句。
对于带有Delay
和Sick
的df
,我的代码有效。但是如果我想修改我的绘图部分,以便我可以在可能只有Delay
或Sick
的df
上使用它,我应该用我的geom_vline
和scale_linetype_manual
part 做什么?例如,如果我想在 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_xxx
的order
参数设置图例的顺序,例如你可以做scale_xxx_yyy(..., guide = guide_legend(order = 1))
让比例/图例出现在顶部,... = 2 第二个等等。根据文档,如果未设置顺序,ggplot2 将通过“...秘密算法”(:(请参阅 ?guide_legend)进行选择。有关不可预测性的更多信息,请参阅***.com/a/70293016/12993861。以上是关于做双图例时如何添加条件语句的主要内容,如果未能解决你的问题,请参考以下文章