change geom_point size on mouse over with plotly

48 Views Asked by At

I have written the following where I have an image in the background (necessary) and some data points:

library(plotly)
library(ggplot2)
library(lorem)

df <- data.frame(
  id = 1:50,
  value = rnorm(50)
)

# background image (necessary)
image_destination <- "https://i.imgur.com/ojTcMtN.jpeg"

gg <- ggplot(df,
             aes(x = id,
                 y = value,
                 text = ipsum_words(50, collapse = F) 
             )
) +
  geom_point(color = "red", alpha = 0.5, size = 5) +
  theme_bw()


# create plot
pp <- ggplotly(gg,
               tooltip = c("text"))

# display plot
plotly::layout(pp,
               # tooltip = c("text"),
               images = list(
                 list(
                   source =  image_destination,
                   xref = "x",
                   yref = "y",
                   x = 0,
                   y = 2,
                   sizex = 100,
                   sizey = 4,
                   sizing = "stretch",
                   opacity = 1,
                   layer = "below"
                 )
               ))

Is there a way to manipulate plotly so that the size of the geom_point increases on mouse over (for example, increase from the current size of 5 to size 10)?

1

There are 1 best solutions below

0
stefan On BEST ANSWER

You can achieve your desired result using two custom event handlers as outlined in the docs. Using the plotly_hover event you can increase the size for the hovered points, using plotly_unhover you can set it back to the defaults. In both cases this achieved using Plotly.restyle. However, using Plotly.restyle we can only set or change the marker style for a trace. Hence, to set the marker style for one point requires that each point is treated as a single trace. To this end I map factor(id) on the color aes in ggplot(). As this will add a color legend I added showlegend = FALSE in layout as setting guide="none" is not accounted for by plotly. Finally, as the units used for sizes differs from ggplot2 getting or setting the correct sizes in plotly requires a conversion of the ggplot2 sizes which can be achieved using Size_in_mm * 96 / 25.4

Note: As the image part is not relevant for the issue, I dropped it to make the example more minimal.

library(plotly)
library(ggplot2)
library(lorem)

set.seed(123)

df <- data.frame(
  id = 1:50,
  value = rnorm(50),
  text = ipsum_words(50, collapse = FALSE)
)

gg <- ggplot(
  df,
  aes(
    x = id,
    y = value,
    text = text,
    color = factor(id)
  )
) +
  geom_point(alpha = 0.5, size = 5) +
  scale_color_manual(
    values = rep("red", nrow(df)), guide = "none"
  ) +
  theme_bw()


# create plot
pp <- ggplotly(gg,
  tooltip = c("text")
)

# display plot
pp <- plotly::layout(pp,
  showlegend = FALSE
) 

pp |>
  htmlwidgets::onRender("
    function(el) {
      el.on('plotly_hover', function(data) {
        console.log(data);
    
        var pn='',
            tn='',
            colors=[];
        
        for(var i=0; i < data.points.length; i++){
          pn = data.points[i].pointNumber;
          tn = data.points[i].curveNumber;
          colors = data.points[i].data.marker.color;
        };
        var size = 10 * 96 / 25.4;
    
        var update = {'marker':{color: colors, size: size, opacity: 1}};
        Plotly.restyle(el.id, update, [tn]);
      });
      el.on('plotly_unhover', function(data) {
        var pn='',
            tn='',
            colors=[];
        
        for(var i=0; i < data.points.length; i++){
          pn = data.points[i].pointNumber;
          tn = data.points[i].curveNumber;
          colors = data.points[i].data.marker.color;
        };
        var size = 5 * 96 / 25.4;
    
        var update = {'marker':{color: colors, size: size, opacity: .5}};
        Plotly.restyle(el.id, update, [tn]);
      });
    }
  ")

enter image description here