我有多个数据集,需要通过单个图形函数运行才能生成一组图形。数据集包含来自两个仪器"G"
和"H"
的测量值。每个Instrument
要么放置在"Up"
位置,要么放置在"Down"
位置,该位置在数据集中会发生变化。现在,我正在尝试在将代码放入函数之前将其固化。
我需要在每个图表中为相同的Position
分配相同的颜色,并且需要用Instrument
和Position
标记系列。所以"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
。