Reputation: 1422
Is there a way of arranging the ggplot legend by groups?
If I try:
library(tidyverse)
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 %>%
ggplot(aes(x = hp, y = qsec, col = make_model)) +
geom_point() +
scale_colour_manual(values = cols_tbl) +
theme(legend.position = "bottom")
The make_model
comes out arranged alphabetically. I can specify the number of rows or columns or even change make_model
to factor but what I'd like is the way they are arranged in the picture below (importantly I want to have an uneven number of items).
Upvotes: 1
Views: 1107
Reputation: 124148
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")
Upvotes: 1