Search code examples
rggplot2plotly

plotly tooltip names returned from ggplot function


I have defined a function that takes a data.frame and returns a plot, which I later on pass to plotly. I need this function to be flexible and it's going to be called a number of times (that's why I wrote a function). A simple reproducible example:

a <- data.frame(x = 1:3, y = c(2, 6, 3))
library(ggplot2)
library(plotly)

plotTrend <- function(x){
   var1 <- names(x)[1]
   var2 <- names(x)[2]
   p <- ggplot(a, aes(x = get(var1), y = get(var2)))+
           geom_point()+
           geom_smooth(method = "lm")
   return(p)
}

Of course I can call plotTrend on a and I'll get the plot I'm expecting.

But when I call ggplotly on it, the tooltip reads an ugly get(var1) instead of the name of the column ("x" in this example).

plotTrend(a)
ggplotly()

I'm aware I could create a text column for the data.frame inside the function, and call ggplotly(tooltip = "text") (I read plenty of questions in SO about that), but I wondered if there's another way to get the right names in the tooltips, either by modifying the function or by using some special argument in ggplotly.

My expected output is:

  • A plotly plot with
  • Tooltips that accurately read the values and whose names are "x" and "y"

Solution

  • We can use aes_string to display the evaluated column names in the ggplotly tooltips:

    library(ggplot2)
    library(plotly)
    
    a <- data.frame(x = 1:3, y = c(2, 6, 3))
    
    var1 <- names(a)[1]
    var2 <- names(a)[2]
    
    p <- ggplot(a, aes_string(x = var1, y = var2)) +
        geom_point()+
        geom_smooth(method = "lm") 
    
    ggplotly(p)
    

    enter image description here

    NB: this works the same inside the plotTrend function call.


    Alternatively, use tidy evaluation to pass the column names as function arguments in the plotTrend function:

    plotTrend <- function(data, x, y) {
    
      x_var <- enquo(x)
      y_var <- enquo(y)
    
      p <- ggplot(data, aes(x = !!x_var, y = !!y_var)) +
          geom_point()+
          geom_smooth(method = "lm") 
    
      return(p)
    
    }
    
    plotTrend(a, x = x, y = y) %>%
        ggplotly()