Home > database >  R: Add multiple colors to the y-axis label in ggplot2 figure
R: Add multiple colors to the y-axis label in ggplot2 figure

Time:08-08

In the example below, is it possible to change the "RED" and "BLUE" text on the y-axis to a block or pill shape that is the actual color (not the words) and the color blocks are the same size? I need to be able to dynamically define the colors using the hex color code.

Thanks!

library(ggplot2)

mtcars |> 
  dplyr::mutate(
    color = 
      c("BLUE", "RED") |> rep_len(dplyr::n()) |> 
      factor()
  ) |> 
  ggplot(aes(x = mpg, y = color))  
  geom_point()  
  labs(y = "")

Created on 2022-08-07 by the enter image description here

CodePudding user response:

AFAIK there is no out of the box option to achieve that, e.g. via ggtext we could only set the text color using some HTML/CSS and ggtext::element_markdown. Hence, the best "hack" I could come up with is to add the pills or boxes using ggtext::geom_textbox which however requires some fiddling or computations to set the x position of the text box, the box width and the box margin:

library(ggplot2)
library(ggtext)

base <- mtcars |> 
  dplyr::mutate(
    color = 
      c("BLUE", "RED") |> rep_len(dplyr::n()) |> 
      factor()
  ) |> 
  ggplot(aes(x = mpg, y = color))  
  geom_point()  
  scale_y_discrete(labels = ~ "BLUEBLUE")   
  scale_fill_identity()  
  labs(y = NULL)  
  coord_cartesian(clip = "off")  
  theme(axis.text.y.left = element_text(color = "transparent"))

base  
  ggtext::geom_textbox(data = ~ dplyr::distinct(.x, color), aes(fill = tolower(color)), label = "BLUE", hjust = 1, box.margin = unit(5, "pt"),
                       x = range(mtcars$mpg)[1] - .05 * diff(range(mtcars$mpg)), color = "transparent",
                       width = unit(.75, "inch"))

And another option would be to simply use geom_label which however requires some more fiddling as e.g. ggtext::geom_textbox offers some additional arguments like box.margin and width.

base  
  geom_label(data = ~ dplyr::distinct(.x, color), aes(fill = tolower(color)), label = "BLUE", hjust = 1, 
             label.r = unit(0.25, "lines"),
                       x = range(mtcars$mpg)[1] - .05 * diff(range(mtcars$mpg)) - .25, color = "transparent")

  • Related