Search code examples
rggplot2ggrepel

Mulitple color in geom_text ggplot2 figure


I would need help in order to color specific part of geom_text label within a ggplot2 figure.

Here is the code I use to produce the example :

library(ggrepel)
set.seed(42)

dat <- subset(mtcars, wt > 2.75 & wt < 3.45)
dat$car <- rownames(dat)

dat$colored_text <- "/A"
dat$car2 <- paste0(dat$colored_text,'-',dat$car)


p <- ggplot(dat, aes(wt, mpg, label = car2)) +
  geom_point(color = "red")

p1 <- p + geom_text() + labs(title = "geom_text()")

Here is the result of p1 :

enter image description here

And I would like to color each / in green and each Letters A in blue and get something like :

enter image description here

DOes someone have an idea to do that please ?


Solution

  • One option to achieve your desired result would be the ggtext package which offers increased text rendering possibilities compared to geom_text and which allows to style text via markdown and or HTML/CSS like so:

    library(ggplot2)
    library(ggtext)
    
    set.seed(42)
    
    dat <- subset(mtcars, wt > 2.75 & wt < 3.45)
    dat$car <- rownames(dat)
    
    dat$colored_text <- "<span style='color: green'>/</span><span style='color: blue'>A</span>"
    dat$car2 <- paste0(dat$colored_text,'-',dat$car)
    
    ggplot(dat, aes(wt, mpg, label = car2)) +
      geom_point(color = "red") + 
      geom_richtext(fill = NA, label.colour = NA) + 
      labs(title = "geom_richtext()")
    

    EDIT Adapting the approach suggested by the author of ggrepel to your case you could get your desired result with ggrepel like so:

    library(ggplot2)
    library(ggrepel)
    
    dat <- subset(mtcars, wt > 2.75 & wt < 3.45)
    dat$car <- rownames(dat)
    
    phantom <- function(x) {
      paste0('phantom("', x, '")')
    }
    
    quotes <- function(x) {
      paste0('"', x, '"')
    }
    dat$label_green <- paste(quotes("/"), phantom('A'), quotes("-"), phantom(dat$car), sep = " * ")
    dat$label_blue <- paste(phantom('/'), quotes("A"), quotes("-"), phantom(dat$car), sep = " * ")
    dat$label_black <- paste(phantom('/'), phantom('A'), quotes("-"), quotes(dat$car), sep = " * ")
    
    ggplot(dat, aes(wt, mpg)) +
      geom_point(color = "red") + 
      geom_text_repel(aes(label = label_green), color = "green", parse = TRUE, seed = 1) +
      geom_text_repel(aes(label = label_blue), color = "blue", parse = TRUE, seed = 1) +
      geom_text_repel(aes(label = label_black), color = "black", parse = TRUE, seed = 1) +
      labs(title = "Multi-color geom_repel_text()")