I am trying to assign colors manually to a ggplot2::ggplot()
boxplot. Using the ggplot2::geom_rect()
function, I know how to assign colors manually to the boxes, and I also know how to assign colors manually to shaded areas in the background for other types of plots like scatterplots. I can't figure out how to manually assign colors to shaded areas in the background for boxplots specifically (when I try to do so, it seems to automatically assign the colors to the boxes and not to the background areas I want to shade), and I also can't figure out hot to assign colors manually to both the boxes and the shaded areas in the background simultaneously.
Here's some made-up data.
Data_Frame <- data.frame(Group_1 = rep(rep(letters[1:2], each = 5), 5), Group_2 = as.character(c(rep(1, 20), rep(2, 30))), Group_3 = rep(rep(LETTERS[1:5], each = 10), length.out = 50), Response_Variable = rnorm(50))
Group_1_Colors <- data.frame(Group_1 = letters[1:2], Group_1_Color = c('red4', 'blue4'))
Group_2_Colors <- data.frame(Group_2 = as.character(1:2), Group_2_Color = c('yellow1', 'purple1'))
Group_2_Colors$Minimum_Horizontal_Cutoff_Value <- c(-Inf, 2.5)
Group_2_Colors$Maximum_Horizontal_Cutoff_Value <- c(2.5, Inf)
Final_Data_Frame <- merge(Data_Frame, Group_2_Colors, by = 'Group_2', all = T)
Final_Data_Frame <- merge(Final_Data_Frame, Group_1_Colors, by = 'Group_1', all = T)
First, we'll load the package.
if (!require (ggplot2)) {
install.packages('ggplot2')
}
library(ggplot2)
Here is a plot where I've assigned colors manually to the boxes and I've shaded areas in the background by another variable.
ggplot2::ggplot(Final_Data_Frame, ggplot2::aes(x = Group_3, y = Response_Variable, fill = Group_1)) +
ggplot2::geom_boxplot() +
ggplot2::scale_fill_manual(values = Group_1_Colors$Group_1_Color) +
ggplot2::geom_rect(ggplot2::aes(xmin = Minimum_Horizontal_Cutoff_Value, xmax = Maximum_Horizontal_Cutoff_Value, ymin = -Inf, ymax = Inf), alpha = 0.009)
When I try to use the 'ggplot2::geom_rect()' function a second time to color the shaded regions in the background manually, it overwrites the previous colors that were assigned to the boxes and colors the boxes with those colors instead.
ggplot2::ggplot(Final_Data_Frame, ggplot2::aes(x = Group_3, y = Response_Variable, fill = Group_1)) +
ggplot2::geom_boxplot() +
ggplot2::scale_fill_manual(values = Group_1_Colors$Group_1_Color) +
ggplot2::geom_rect(ggplot2::aes(xmin = Minimum_Horizontal_Cutoff_Value, xmax = Maximum_Horizontal_Cutoff_Value, ymin = -Inf, ymax = Inf), alpha = 0.009) +
ggplot2::scale_fill_manual(values = Group_2_Colors$Group_2_Color)
Are there any solutions? This question seemed like it would help, but I still can't figure it out. Even if the question I linked to in the previous sentence helped, I don't think it'd be possible to split up the legend into two groups, Group_2
and Group_3
, which are the two separate groups I'm hoping to color manually; I'd like to break up the legend by these two groups too.
Thanks!
You could get a separate legend for the rectangles easily by using the ggnewscale
package which allows to have multiple scales and legends for the same aesthetic.
Note: Also note that IMHO it would be easier to work with a separate data frame for the background rectangles. Putting all information in one data frame has the side effect that you are drawing multiple rectangles on top of each other and is the reason you have to set a very small alpha
value.
library(ggplot2)
ggplot(
Final_Data_Frame,
aes(
x = Group_3, y = Response_Variable,
fill = Group_1
)
) +
geom_boxplot() +
scale_fill_manual(
values = Group_1_Colors$Group_1_Color
) +
ggnewscale::new_scale_fill() +
geom_rect(
data = Group_2_Colors,
aes(
xmin = Minimum_Horizontal_Cutoff_Value,
xmax = Maximum_Horizontal_Cutoff_Value,
ymin = -Inf, ymax = Inf,
fill = factor(Group_2)
),
alpha = 0.2,
inherit.aes = FALSE
) +
scale_fill_manual(
values = Group_2_Colors$Group_2_Color,
name = "Group_2"
)