One option to achieve your desired result would be to make use of the ggnewscale
package which allows for multiple color scales. One drawback of this approach is that it requires plotting your data via multiple geom
layers too. In my approach below I first split the data as well as the color vectors by groups. To get the order of the groups right it's best make use of the order
argument of guide_legend
. Additionally I make use of the title.theme
argument to "remove" the duplicated legend titles. Finally I use theme
options to align the guides vertically and to the left.
library(tidyverse)
library(ggnewscale)
mtcars_tbl <- mtcars %>%
rownames_to_column(var = "make_model") %>%
as_tibble %>%
mutate(point_col = case_when(cyl == 4 ~ "#009E73",
cyl == 6 ~ "#0072B2",
cyl == 8 ~ "#D55E00"))
cols_tbl <- mtcars_tbl %>%
select(make_model, point_col) %>%
deframe()
mtcars_tbl <- split(mtcars_tbl, mtcars_tbl$cyl)
cols_tbl <- lapply(mtcars_tbl, function(x) x %>% select(make_model, point_col) %>% deframe())
ggplot(mapping = aes(x = hp, y = qsec)) +
geom_point(data = mtcars_tbl$`4`, aes(col = make_model)) +
scale_colour_manual(values = cols_tbl$`4`,
guide = guide_legend(order = 1, title.theme = element_text(color = NA))) +
new_scale_color() +
geom_point(data = mtcars_tbl$`6`, aes(col = make_model)) +
scale_colour_manual(values = cols_tbl$`6`,
guide = guide_legend(order = 2, title.theme = element_text(color = "black"))) +
new_scale_color()+
geom_point(data = mtcars_tbl$`8`, aes(col = make_model)) +
scale_colour_manual(values = cols_tbl$`8`,
guide = guide_legend(order = 3, title.theme = element_text(color = NA))) +
theme(legend.position = "bottom",
legend.box = "vertical",
legend.box.just = "left")
