Using tidyverse and the mtcars dataset, I am plotting the model and mpg of each car. I would like the axis text color of each car model to reflect the make of the car (for example, Toyota = red, Cadillac = blue…etc). How can I do this?
Example Dataset
library(tidyverse)
# Create make and model for each car
mtcars <- mtcars %>%
rownames_to_column(var = 'car') %>%
filter(!car %in% c('Mazda RX4 Wag', 'Hornet 4 Drive', 'Valiant', 'Ford Pantera L')) %>%
separate_wider_delim(car, " ", names = c('make', 'model'), cols_remove = FALSE) %>%
select(car, make, model, mpg)
head(mtcars)
#> # A tibble: 6 Ă— 4
#> car make model mpg
#> <chr> <chr> <chr> <dbl>
#> 1 Mazda RX4 Mazda RX4 21
#> 2 Datsun 710 Datsun 710 22.8
#> 3 Hornet Sportabout Hornet Sportabout 18.7
#> 4 Duster 360 Duster 360 14.3
#> 5 Merc 240D Merc 240D 24.4
#> 6 Merc 230 Merc 230 22.8
# How can I make the y-axis text color reflect the make of each model?
mtcars %>%
ggplot(aes(x = mpg, y = model)) +
geom_point() +
labs(y = NULL) +
scale_x_continuous(breaks = seq(0, 35, 5), limits = c(0,35)) +
theme_bw()
Created on 2023-12-06 with reprex v2.0.2
- Here is a similar SO question that uses an example with only two categories (this example has 20; link here)
>Solution :
It’s officially unsupported to have vectorised colors in theme elements, but it does work, so you could do:
mtcars %>%
ggplot(aes(x = mpg, y = model)) +
geom_point() +
labs(y = NULL) +
scale_x_continuous(breaks = seq(0, 35, 5), limits = c(0,35)) +
theme_bw() +
theme(axis.text.y = element_text(
color = scales::hue_pal()(length(levels(factor(mtcars$make))))[
as.numeric(factor(mtcars$make))]
))
Personally, I would avoid using colors and a legend for axis labels. Why not directly label with facets?
mtcars %>%
ggplot(aes(x = mpg, y = model)) +
geom_point() +
labs(y = NULL) +
scale_x_continuous(breaks = seq(0, 35, 5), limits = c(0,35)) +
theme_minimal() +
theme(panel.spacing.y = unit(0, "mm"),
strip.text.y.left = element_text(angle = 0),
strip.background = element_rect(fill = "gray90", color = "white",
linewidth = 1.5),
strip.placement = "outside") +
facet_grid(make~., scales = "free_y", space = "free_y", switch = "y")

