rggplot2ggiraphggiraphextra

Adding an image in tooltip of ggRadar


Goal

I want to display images based on a column containing local/external url of images in a radar chart.

Reproducible Example

This is possible for a bar chart with ggiraph as shown below:

require(ggplot2)
require(ggiraph)
require(ggiraphExtra)

# Sample image
mtcars$gif_link <-"https://media.giphy.com/media/rrmf3fICPZWg1MMXOW/giphy.gif" 
mtcars$model <- row.names(mtcars)

# Create a ggplot object with interactivity using ggiraph
gg <- ggplot(mtcars, aes(y = as.factor(am), x = mpg)) +
  geom_bar_interactive(aes(tooltip = paste(model, "<img src=", shQuote(gif_link), " height='100'>")), stat = "identity") +
  theme_minimal()

# Display the ggiraph object
girafe(ggobj = gg)  

But it doesn't work with ggRadar:

ggRadar(data  =mtcars, aes(colour=am,
                           tooltip = paste(model, "<img src=", shQuote(gif_link), " height='100'>")),
        interactive=TRUE)
Error in `[.data.frame`(data, groupvar) : undefined columns selected  

I am open to using any other package/method that would achieve my goal.


Solution

  • One option would be to build your radar chart from scratch which requires some effort including some data wrangling but gives you all the flexibility of ggiraph:

    library(ggplot2)
    library(ggiraph)
    library(ggiraphExtra)
    library(dplyr)
    
    mtcars2 <- mtcars
    
    gg <- mtcars2 |>
      mutate(
        across(-am, ~ (.x - min(.x)) / diff(range(.x)))
      ) |>
      group_by(am) |>
      summarise(across(everything(), mean), .groups = "drop") |>
      tidyr::pivot_longer(-am, names_to = "variable") |>
      arrange(am, variable) |>
      mutate(gif_link = "https://media.giphy.com/media/rrmf3fICPZWg1MMXOW/giphy.gif") |>
      ggplot(aes(
        x = variable, y = value,
        colour = factor(am), fill = factor(am), group = factor(am)
      )) +
      geom_polygon_interactive(alpha = 0.3) +
      geom_point_interactive(
        aes(tooltip = paste0(
          "<i>am:</i> ", am,
          "<br>",
          "<i>", variable, ":</i> ", round(value, 1),
          "<br>",
          "<img src=", shQuote(gif_link), " height='100'>"
        )),
        size = 3
      ) +
      coord_radar()
    
    girafe(ggobj = gg)
    

    enter image description here

    EDIT Following this answer we could add local images by wrapping in base64enc::dataURI(). In the code below I download the R logo and add it as local image:

    path <- tempdir()
    download.file(
      "https://www.r-project.org/logo/Rlogo.png",
      file.path(path, "RLogo.png")
    )
    gg <- mtcars2 |>
      mutate(
        across(-am, ~ (.x - min(.x)) / diff(range(.x)))
      ) |>
      group_by(am) |>
      summarise(across(everything(), mean), .groups = "drop") |>
      tidyr::pivot_longer(-am, names_to = "variable") |>
      arrange(am, variable) |>
      ggplot(aes(
        x = variable, y = value,
        colour = factor(am), fill = factor(am), group = factor(am)
      )) +
      geom_polygon_interactive(alpha = 0.3) +
      geom_point_interactive(
        aes(tooltip = paste0(
          "<i>am:</i> ", am,
          "<br>",
          "<i>", variable, ":</i> ", round(value, 1),
          "<br>",
          "<img src=", base64enc::dataURI(file = file.path(path, "RLogo.png")),
          " height='100'>"
        )),
        size = 3
      ) +
      coord_radar()
    
    girafe(ggobj = gg)
    

    enter image description here