Search code examples
rggplot2plotlyggplotlyggtext

Trying to add color coding to the title of ggplotly


I am trying to produce a graph where the title has color coded text to remove the need for a legend. I have no problem doing this in ggplot2 using the ggtext package and ggtext::element_markdown(). However, when I try to then layer on top ggplotly, the color disappears.

I am wondering if there is any way to combine the color functionality with ggplotly?

Here is a sample reproducible example using the mtcars dataset.

library(ggplot2)
library(dplyr)
library(plotly)
library(ggtext)

mtcolors<-c("springgreen4", "darkorange3", "purple")
names(mtcolors)<-c("4 cyl", "6 cyl", "8 cyl")

mt_title_text <- glue::glue(
  'MPG vs HP -',  
  '<span style = "color:{mtcolors["4 cyl"]}">**4 cyl**</span>', 
  'vs.',
  '<span style = "color:{mtcolors["6 cyl"]}">**6 cyl**</span>',
  'vs.',
  '<span style = "color:{mtcolors["8 cyl"]}">**8 cyl**</span>',
  .sep = ' '
)

mtcars |>
  mutate(
    cyl = as.factor(cyl)
  ) |>
  ggplot(aes(x=mpg, y=hp, color=cyl)) +
  geom_point(size=3) +
  theme_bw() +
  scale_color_manual(values=c("springgreen4", "darkorange3", "purple")) +
  labs(
    title = mt_title_text
  ) +
  theme(
    plot.title = ggtext::element_markdown(),
    panel.grid.minor = element_blank(),
    legend.position = 'none'
  ) 

This produces the following graph:

enter image description here

However, when I add ggplotly to add the interactive functionality, the markdown text in the title returns to just normal text:

mtcarsexp<-
  mtcars |>
  mutate(
    cyl = as.factor(cyl)
  ) |>
  ggplot(aes(x=mpg, y=hp, color=cyl)) +
  geom_point(size=3) +
  theme_bw() +
  scale_color_manual(values=c("springgreen4", "darkorange3", "purple")) +
  labs(
    title = mt_title_text
  ) +
  theme(
    plot.title = ggtext::element_markdown(),
    panel.grid.minor = element_blank(),
    legend.position = 'none'
  ) 

ggplotly(mtcarsexp)

enter image description here

It seems that perhaps I could use the concept in this question and, rather than use the title in the labs, just create text, and position it in the place of the title, but I would much prefer to use the native labs functionality.


Solution

  • You need to use html tags with ggplotly. Also, colors need to be either standard colors or the HEX codes.

    library(ggplot2)
    library(dplyr)
    library(plotly)
    
    mtcolors<-c("#00FF7F", "darkorange", "purple")
    names(mtcolors)<-c("4 cyl", "6 cyl", "8 cyl")
    
    mt_title_text <- glue::glue(
      'MPG vs HP -',  
      '<b style= "color:{mtcolors["4 cyl"]}">4 cyl</b>', 
      'vs.',
      '<b style= "color:{mtcolors["6 cyl"]}">6 cyl</b>',
      'vs.',
      '<b style= "color:{mtcolors["8 cyl"]}">8 cyl</b>',
      .sep = ' ')
    
    mtcars %>% 
      mutate(
        cyl = as.factor(cyl)
      ) %>% 
      ggplot(aes(x=mpg, y=hp, color=cyl)) +
      geom_point(size=3) +
      theme_bw() +
      scale_color_manual(values=c("springgreen4", "darkorange3", "purple")) +
      labs(
        title = mt_title_text
      ) +
      theme(
        panel.grid.minor = element_blank(),
        legend.position = 'none'
      ) -> p
    
    ggplotly(p)
    

    Created on 2024-03-11 with reprex v2.0.2