0

I'm doing a Shiny app, but in the spirit of making a minimal reproduceable example, I took the Shiny part out. This is just context.

I want to make a plot with the ggplotly() function. It works fine until I try to change the tooltip. Without that, my code would look like this:

library(ggplot2)
library(plotly)

n <- 100
samples <- n
act.rec <- n
while(n != 0) {
  rand <- ceiling(runif(n, 0, 2))
  act <- length(rand[rand == 2])
  act.rec <- c(act.rec, act)
  n <- n-act
  samples <- c(samples, n)
}
test <- data.frame(act = c(act.rec, 0), samples = c(samples, 0), hl = 0:length(samples))
test2 <- test
test2$samples <- 100-test$samples
test <- rbind(cbind(test, dec = "Not decayed"), cbind(test2, dec = "Decayed"))

p <- ggplot(test, aes(x = hl, y = samples, colour = dec))+
  stat_smooth(method = "nls", size = 0.8,
              formula = y ~ SSasymp(x, Asym, R0, lrc), se = FALSE)+
      geom_point(shape = 4, size = 3)+
      theme_minimal()+
      scale_colour_discrete(name = "Decay Status")+
      xlab("Half Lives")+
      ylab("Atoms")

ggplotly(p)

This is a simulation of the half-lives of radioactive elements (again, context). After that, I tried adding the text argument in the geom_point() geom. That works fine; if I hover over the crosses, it shows me what I want:

[...]
geom_point(shape = 4, size = 3, aes(text = paste(
        "Half-lives: ", hl,
        "\nAtoms: ", samples,
        "\nDecay Status: ", dec
      ) ))+
[...]

ggplotly(p, tooltip = "text")

Just a snapshot: enter image description here However, when I try to do the same with stat_smooth, it disappears.

[...]
stat_smooth(method = "nls", size = 0.8,
              formula = y ~ SSasymp(x, Asym, R0, lrc), se = FALSE,
              aes(text = paste(
                "Half-lives: ", hl,
                    "\nAtoms: ", samples,
                    "\nDecay Status: ", dec
                  ) ))+
[...]

ggplotly(p, tooltip = "text")

enter image description here

By the way, it I just do ggplotly(p), it has the same effect, only that the tooltip that does exist shows everything twice, once the way I want, once the way it was before. But this is not the point.

I've read multiple posts, like this one, from which I got the idea to use label instead of text and this one, which hasn't been answered yet. Using label did me nothing – literally. The line didn't disappear, but the tooltip didn't work. enter image description here

I've got to say, I don't know what to do next. I really hope someone can find out what's wrong, or maybe geom_smooth (or stat_smooth) is a special case. Either way, thanks in advance.

PS (edit 2): I also discovered that, if I don't put any variables in text, it works fine:

[...]
stat_smooth(method = "nls", size = 0.8,
              formula = y ~ SSasymp(x, Asym, R0, lrc), se = FALSE,
              aes(text = paste(
                "Half-lives: "
                  ) ))+
[...]
ggplotly(p)

enter image description here

EDIT: My current code is:

library(ggplot2)
library(plotly)

n <- 100
samples <- n
act.rec <- n
while(n != 0) {
  rand <- ceiling(runif(n, 0, 2))
  act <- length(rand[rand == 2])
  act.rec <- c(act.rec, act)
  n <- n-act
  samples <- c(samples, n)
}
test <- data.frame(act = c(act.rec, 0), samples = c(samples, 0), hl = 0:length(samples))
test2 <- test
test2$samples <- 100-test$samples
test <- rbind(cbind(test, dec = "Not decayed"), cbind(test2, dec = "Decayed"))

p <- ggplot(test, aes(x = hl, y = samples, colour = dec))+
  stat_smooth(method = "nls", size = 0.8,
              formula = y ~ SSasymp(x, Asym, R0, lrc), se = FALSE,
              aes(label = paste(
                "Half-lives: ", hl,
                    "\nAtoms: ", samples,
                    "\nDecay Status: ", dec
                  ) ))+
      geom_point(shape = 4, size = 3, aes(text = paste(
        "Half-lives: ", hl,
        "\nAtoms: ", samples,
        "\nDecay Status: ", dec
      ) ))+
      theme_minimal()+
      scale_colour_discrete(name = "Decay Status")+
      xlab("Half Lives")+
      ylab("Atoms")

ggplotly(p)
Érico Patto
  • 1,015
  • 4
  • 18

1 Answers1

0

I am not sure why, but stat_smooth seems to have an issue with defining a tooltip text inside aes. A workaround is to hack into the plotly_build object as shown below.

n <- 100
samples <- n
act.rec <- n
while(n != 0) {
  rand <- ceiling(runif(n, 0, 2))
  act <- length(rand[rand == 2])
  act.rec <- c(act.rec, act)
  n <- n-act
  samples <- c(samples, n)
}
test <- data.frame(act = c(act.rec, 0), samples = c(samples, 0), hl = 0:length(samples))
test2 <- test
test2$samples <- 100-test$samples
test <- rbind(cbind(test, dec = "Not decayed"), cbind(test2, dec = "Decayed"))
#text <- paste("Half-lives: ", test$hl, "\nAtoms: ", test$samples,"\nDecay Status: ", test$dec )

p <- ggplot(test, aes(x = hl, y = samples, colour = dec)) +
  geom_point(shape = 4, size = 3) +
  stat_smooth(method = "nls", size = 0.8, 
              formula = y ~ SSasymp(x, Asym, R0, lrc), se = FALSE) +
  theme_minimal()+
  scale_colour_discrete(name = "Decay Status")+
  xlab("Half Lives")+
  ylab("Atoms")

pp <- plotly_build(p)

pp31 <- pp$x$data[[1]]
pp32 <- pp$x$data[[2]]
pp33 <- pp$x$data[[3]]
pp34 <- pp$x$data[[4]]

pp$x$data[[1]]$text <- paste("Half-lives: ", pp31$x, "<br>Atoms: ", pp31$y, "<br>Decay Status: ", pp31$name)
pp$x$data[[2]]$text <- paste("Half-lives: ", pp32$x, "<br>Atoms: ", pp32$y, "<br>Decay Status: ", pp32$name)
pp$x$data[[3]]$text <- paste("Half-lives: ", pp33$x, "<br>Atoms: ", pp33$y, "<br>Decay Status: ", pp33$name)
pp$x$data[[4]]$text <- paste("Half-lives: ", pp34$x, "<br>Atoms: ", pp34$y, "<br>Decay Status: ", pp34$name)

plotly_build(pp)

output

YBS
  • 19,324
  • 2
  • 9
  • 27