Search code examples
rggplot2ggplotly

Customizing tooltip using ggplotly and geom_density


I'm trying to create a tooltip that shows the density as well as the x-axis information using ggplot and ggplotly.

Using the mtcars data sets, I wanted to just create a tooltip for the density of the mpg that was cleaner.

The basic plot I was trying to create was using

data(mtcars)
ggplotly(
  ggplot(mtcars)+
    geom_density(
      aes(x = mpg,
          y = ..scaled..)
    )+
    scale_y_continuous(
      name = 'Counters', 
      sec.axis = sec_axis(~ . * (max_dens/max_hist)*10, name = 'Density'))
  )

which produces enter image description here

This tooltip is working, but I would essentially like to change the 'scaled' to something else. I've tried added the text to the aes like:

ggplotly(
  ggplot(mtcars)+
    geom_density(
      aes(x = mpg,
          y = ..scaled..,
          text = paste('testing',mpg))
    )
)

But that just creates a new density for each mpg.

The full example I want to use is combining both a histogram and density like:


data(mtcars)
nbins = 20
df = mtcars
min.brea <- round_any(min(df$mpg), diff(range(df$mpg))/nbins, floor)
max.brea <- round_any(max(df$mpg), diff(range(df$mpg))/nbins, ceiling)
breaks <- seq(min.brea, max.brea, diff(range(df$mpg/nbins)))
histdata <- hist(df$mpg, breaks=breaks, plot=FALSE, right=FALSE)

max_hist <- max(histdata$counts)
max_dens <- max(density(df$mpg)$y)


ggplotly(
  ggplot(mtcars)+
    geom_histogram(
      aes(x = mpg,
          text = paste('Testing', mpg)
      ),
      bins = 30,
      color = 'black',
      fill = 'white'
    )+
    geom_density(
      aes(x = mpg,
          y = ..scaled..*(max_hist),
          text = paste('Testing', mpg, max_hist*..scaled..))
    )+
    scale_y_continuous(
      name = 'Counters', 
      sec.axis = sec_axis(~ . * (max_dens/max_hist), name = 'Density')),
  tooltip = 'text')

But this really messes up the tooltip.

I was hoping there was a way to specify the tooltips for each one individually to be cleaner on the output side of things. Eventually this will go into an Rshiny app.


Solution

  • You can't combine columns from the original data with columns from the data after the stat is applied. The only reason you don't get an error when doing paste('Testing', mpg, max_hist * ..scaled..)) is that in this case the dataset mpg from the global environment is used which results in the messed up tooltip. Instead use the x column computed by the stat, i.e. do paste('Testing',..x.., max_hist * ..scaled..)). Additionally note that I switched to after_stat as the .. notation was deprecated in ggplot2 3.4.0.

    library(ggplot2)
    library(plotly)
    
    ggplot(mtcars) +
      geom_histogram(
        aes(
          x = mpg,
          text = paste("Testing", mpg)
        ),
        bins = 30,
        color = "black",
        fill = "white"
      ) +
      geom_density(
        aes(
          x = mpg,
          y = max_hist * after_stat(scaled),
          text = after_stat(paste("Testing", x, max_hist * scaled))
        )
      ) +
      scale_y_continuous(
        name = "Counters",
        sec.axis = sec_axis(~ . * (max_dens / max_hist), name = "Density")
      )
    
    ggplotly(tooltip = "text")
    

    enter image description here