r语言 - 在 ggplot2 中使用正则表达式为变量分配特定颜色



我有多个数据集,需要通过单个图形函数运行才能生成一组图形。数据集包含来自两个仪器"G""H"的测量值。每个Instrument要么放置在"Up"位置,要么放置在"Down"位置,该位置在数据集中会发生变化。现在,我正在尝试在将代码放入函数之前将其固化。

我需要在每个图表中为相同的Position分配相同的颜色,并且需要用InstrumentPosition标记系列。所以"Position" == "Up & "Instrument" == "G""Position" == "Up" & "Instrument" == "H"需要相同的颜色。我想使用wesanderson包、"Cavalcanti1"调色板、颜色 2 和 3。Position"Up"为颜色 2,Position"Down"为颜色 3。

这个问题和这个问题几乎很有帮助,但我的系列名称会随着每个数据集而变化。我认为使用正则表达式来识别legend_title列中的"Up""Down"字符串(如scale_color_manual(values = c("foo" = "#999999", "bar" = "#E69F00"))(可能是一种解决方案,但我的图形代码不断出现错误。

我刚刚开始学习更多关于正则表达式的知识。你能在像 grep(( 这样的正则表达式函数之外使用它吗?还是 scale_color_manual(( 接受该语法为值分配特定颜色?任何想法或建议不胜感激!

这是我的数据和代码的简化版本:

library(dplyr)
library(ggplot2)
library(hms)
library(wesanderson) # color palette I want to use
df1 <- data.frame(Time = as.hms(c("11:30:00", "11:30:30", "11:31:00", "11:30:00", "11:30:30", "11:31:00")),
Chl = c(3.1,3.6,4,2.2,2,1.8),
Instrument = c('H','H','H','G','G','G'),
Position = c('Up','Up','Up','Down','Down','Down'))
df1$Instrument <- as.character(df1$Instrument) #to mimic my actual data
df1$Position <- as.character(df1$Position) 
df2 <- data.frame(Time = as.hms(c("09:30:00", "09:30:30", "09:31:00", "09:30:00", "09:30:30", "09:31:00")),
Chl = c(3.0,3.5,3.7,1.5,1.3,1.0),
Instrument = c('H','H','H','G','G','G'),
Position = c('Down','Down','Down','Up','Up','Up'))
df2$Instrument <- as.character(df2$Instrument)#to mimic my actual data
df2$Position <- as.character(df2$Position)
### test code chunks for function. Paste in df1 or df2
modify_df <- df2 %>% 
mutate(legend_title = paste0(Position, ' ', Instrument))
# Create column with desired series names/labels
(one_plot = ggplot(data = modify_df, aes(x = Time, y = Chl, color = legend_title)) +
geom_line(size = .5) +
scale_color_manual(values = c("^Down" = wes_palette("Cavalcanti1")[3],
"^Up" = wes_palette("Cavalcanti1")[2])) + # regular expression to look for Up or Down at the beginning of the text 
theme(axis.text.x = element_text(angle = 45, hjust = 1),
legend.title = element_blank()) +
labs(x = ""))

只需在scale_color_manual中调用四种组合:

scale_color_manual(values = c("Down G" = wes_palette("Cavalcanti1")[3],
"Down H" = wes_palette("Cavalcanti1")[3],
"Up G" = wes_palette("Cavalcanti1")[2],
"Up H" = wes_palette("Cavalcanti1")[2]))

这是一个更通用的解决方案,它将根据位置值对标签进行排序。

我没有安装wesanderson软件包,所以我用绿色和红色代替。 在这种情况下,ggplot将根据颜色对图例进行排序,因此绿色是第一位的,红色是第二位的。 这用你的颜色组合对我的更改进行排序,如果是这样,请从订单功能中删除decreasing =TRUE

有了这个事实,就要按正确的顺序获取标签。 在这种情况下,我对两个基于 TRUE/FALSE 的字符串中包含字符"Up"进行了排序。 现在将有序标签向量传递给 ggplot 调用。

有关详细信息,请参阅注释。

modify_df<-df2
#Create new column setting color to desired pallete
modify_df$color<-ifelse(modify_df$Position == "Up", "green", "red")
#create the labels 
modify_df$label<-paste(modify_df$Instrument, modify_df$Position)
#Create labels and sort labels so that the one contain Up is always first
labels<-unique(modify_df$label)
labels<-labels[order(grepl("Up", labels), decreasing =TRUE)]
#plot
one_plot = ggplot(data = modify_df, aes(x = Time, y = Chl, color = color)) +
geom_line(size = .5) +
scale_color_identity(guide="legend" , label=labels)  +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
legend.title = element_blank()) +
labs(x = "")
one_plot
##removed added columns if necessary
#modify_df<-modify_df %>% select(-color, -label)

您可以通过在调用scale_color_manual中使用条件来做到这一点,例如

ggplot(modify_df, aes(x = Time, y = Chl, color = legend_title)) +
geom_line(size = 0.5) +
scale_color_manual(values = sapply(modify_df$legend_title, function(i) ifelse(grepl("Down", i), 
wes_palette("Cavalcanti1")[3],
wes_palette("Cavalcanti1")[2]))) +
theme(axis.text.x = element_text(angle = 45, hjust = 1),
legend.title = element_blank()) +
labs(x = "")

如果您的条件和颜色集增长,您可以使用一系列if语句来代替该ifelse

最新更新