Description
Thank you for amazing packages. I am working on a series of reports, each report containing a different dataset and multiple plots, and I need colors to match between plots and reports. I am avoiding RColorBrewer (e.g. myColors <- brewer.pal(5,"Set1") ) because we have already published some of the first reports using other colours that we want to keep.
This was my original good function:
scale_color_test <- function(...){
ggplot2:::manual_scale(
"color",
values = setNames(c("grey50","gold", "blue2" ,"green3" , "red3"),
c("color_grey","color_gold","color_blue","color_green","color_red")),
labels = setNames(c("color grey","color gold","color blue","color green","color red"),
c("color_grey","color_gold","color_blue","color_green","color_red")),
drop=TRUE)
}
But this function recently stopped dropping unused values in the legends (exact same script run before and after a recent update).
Here is my reproducible example, and some of the things I have tried to fix this issue:
df.temp1<-data.frame(var1=factor(c("color_grey","color_gold","color_blue","color_green","color_red")),
var2=c(1,2,3,4,5),
var3=c(9,8,6,5,4),
var4=c("these colors","these colors","these colors","those colors","those colors"))
df.temp2<-data.frame(var1=factor(c("color_gold","color_blue","color_red")),
var2=c(2,3,5),
var3=c(8,6,4),
var4=c("these colors","these colors","those colors"))
My old approach that used to work (second plot not dropping unused values in legend anymore):
scale_color_test <- function(...){
ggplot2:::manual_scale(
"color",
values = setNames(c("grey50","gold", "blue2" ,"green3" , "red3"),
c("color_grey","color_gold","color_blue","color_green","color_red")),
labels = setNames(c("color grey","color gold","color blue","color green","color red"),
c("color_grey","color_gold","color_blue","color_green","color_red")),
drop=TRUE)
}
ggplot(df.temp1, aes(x=var2, y=var3,color=var1))+
geom_point(shape=21,stroke=1,size=4)+
scale_color_test()+
facet_grid(rows = vars(var4))+
theme_bw()
ggplot(df.temp2, aes(x=var2, y=var3,color=var1))+
geom_point(shape=21,stroke=1,size=4)+
scale_color_test()+
facet_grid(rows = vars(var4))+
ggtitle("This plot should have gold, blue and red")+
theme_bw()
Using scale_color_manual (drops, but colors not assigned to values):
note: if I add setNames to values, then I am back to not droppping unused levels.
scale_color_test <- scale_color_manual(
name = factor(c("color_grey","color_gold","color_blue","color_green","color_red")),
values = c("grey50","gold", "blue2" ,"green3" , "red3"),
labels = setNames(c("color grey","color gold","color blue","color green","color red"),
c("color_grey","color_gold","color_blue","color_green","color_red")),
drop=TRUE)
ggplot(df.temp1, aes(x=var2, y=var3,color=var1))+
geom_point(shape=21,stroke=1,size=4)+
scale_color_test+
facet_grid(rows = vars(var4))+
theme_bw()
ggplot(df.temp2, aes(x=var2, y=var3,color=var1))+
geom_point(shape=21,stroke=1,size=4)+
scale_color_test+
facet_grid(rows = vars(var4))+
ggtitle("This plot should have gold, blue and red")+
theme_bw()
Then I tried creating a custom palette following this example:
https://drsimonj.svbtle.com/creating-corporate-colour-palettes-for-ggplot2
I simply don't know what pattern it follows, it is just not working as it should:
mycolors <- c(color_grey = "#7F7F7F", color_gold = "#FFD700",
color_blue = "#0000EE", color_green = "#00CD00",
color_red = "#CD0000")
mypalette <- function(...) {
cols <- c(...)
if (is.null(cols))
return (mycolors)
mycolors[cols]
}
my_palettes <- list(
main
= mypalette("color_grey","color_gold","color_blue","color_green","color_red"))
my_pal <- function(palette = "main", reverse = FALSE, ...) {
pal <- my_palettes[[palette]]
if (reverse) pal <- rev(pal)
colorRampPalette(pal, ...)
}
scale_color_test <- function(palette = "main", discrete = TRUE, reverse = FALSE, ...) {
pal <- my_pal(palette = palette, reverse = reverse)
if (discrete) {
discrete_scale("colour", paste0("my_", palette), palette = pal, ...)
} else {
scale_color_gradientn(colours = pal(256), ...)
}
}
ggplot(df.temp1, aes(x=var2, y=var3,color=var1))+
geom_point(shape=21,stroke=1,size=4)+
scale_color_test(palette="main")+
facet_grid(rows = vars(var4))+#scales = "free", space = "free"
theme_bw()
ggplot(df.temp2, aes(x=var2, y=var3,color=var1))+
geom_point(shape=21,stroke=1,size=4)+
scale_color_test(palette="main")+
facet_grid(rows = vars(var4))+#scales = "free", space = "free"
ggtitle("The other one has grey to color_blue, gold to gold, blue to color_green, green to color_grey and red to red")+
theme_bw()
I have also found two other issues related to drop=TRUE failing to drop unused values, but they were using scale_discrete with limits and I could not see how their fixes could help me.
I have run this example with two versions (rswitch):
"R version 3.6.1 (2019-07-05)"
packageVersion("Tidyverse")
[1] ‘1.3.1’
packageVersion("ggplot2")
[1] ‘3.3.4’
AND:
"R version 4.1.0 (2021-05-18)"
packageVersion("Tidyverse")
[1] ‘1.3.1.9000’
packageVersion("ggplot2")
[1] ‘3.3.5’
Million thanks for help