11

This is my input dataset:

> names(breakingbad.episodes)
[1] "season"           "episode"          "epnum"            "epid"             "title"           
[6] "url.trakt"        "firstaired.utc"   "id.tvdb"          "rating"           "votes"           
[11] "loved"            "hated"            "overview"         "firstaired.posix" "year"            
[16] "zrating.season"   "src"     

For my ggvis, I'm using the following variables firstaired.posix and rating:

> str(breakingbad.episodes[c("firstaired.posix", "rating")])
'data.frame':   62 obs. of  2 variables:
$ firstaired.posix: POSIXct, format: "2008-01-21 02:00:00" "2008-01-28 02:00:00" "2008-02-  11 02:00:00" ...
$ rating          : num  87 85 84 84 83 90 87 85 88 83 ...

I successfully created my ggvis with a tooltip containing the rating information like this:

> breakingbad.episodes %>% 
ggvis(x = ~firstaired.posix, 
    y = ~rating, 
    fill = ~season) %>% 
layer_points() %>%
add_axis("x", title = "Airdate") %>%
add_axis("y", title = "Rating") %>%
add_legend("fill", title = "Season") %>%
add_tooltip(function(data){paste0("Rating: ", data$rating)}, "hover")

But I actually want the tooltip to contain more data, like the epid variable, so I tried:

…
add_tooltip(function(data){paste0("Rating: ", data$rating, "\n", "Epid: ", as.character(data$epid))}, "hover")

…Using as.character() because epid is an ordered factor – But the part of the tooltip is empty. (I also noticed the linebreak I intended \n to insert is missing, but that's a different problem).

It looks like the cause of this problem is that the vis object created by piping my dataset into ggvis doesn't contain the information I want to display, at least that's why I gathered by looking through the output of str() on the first example.

EDIT: I solved that linebreak issue, so there's no need to point me to ?add_tooltip – totally forgot about that.

EDIT: The accepted answer is working fine, even though it doesn't let me put arbitrary variables in the tooltip, it's pretty much what I need for my usecase, thanks! Here's what I did in the end:

breakingbad.episodes <- transform(breakingbad.episodes, id = paste0(epid, " - ", title))

breakingbad.episodes %>% 
  ggvis(x = ~firstaired.posix, 
      y = ~rating, 
      fill = ~season, 
      key := ~id) %>% 
  layer_points() %>%
  add_axis("x", title = "Airdate") %>%
  add_axis("y", title = "Rating") %>%
  add_legend("fill", title = "Season") %>%
  add_tooltip(all_values, "click")
Jemus42
  • 629
  • 9
  • 24

2 Answers2

20

Yes, it's possible. Normally the client only sends back the columns of data that are actually in the plot. To get other columns, you should use a key to index into the original data: This is simple reproducible example

library(ggvis)
mtc <- mtcars
mtc$id <- 1:nrow(mtc)

all_values <- function(x) {
  if(is.null(x)) return(NULL)
  row <- mtc[mtc$id == x$id, ]
  paste0(names(row), ": ", format(row), collapse = "<br />")
}

mtc %>% ggvis(x = ~wt, y = ~mpg, key := ~id) %>%
  layer_points() %>%
  add_tooltip(all_values, "hover")
Koundy
  • 5,265
  • 3
  • 24
  • 37
  • Thanks! I've chosen your answer as accepted because it covers the same solution as the previous answer, but also provides a simple reproducible example. – Jemus42 Jul 02 '14 at 12:59
  • this is great. it would be even better if the tooltip would not be in a clunky serif font. – Henk Jul 16 '14 at 13:13
  • 3
    Is there any known drawback to this approach that is dependent on the type of plot? I have an example where i have a layer_lines() layer and a layer_points() layer. When I add the "key := ~id" input to the ggvis, it oddly makes the layer_lines() disappear from the plot. It is a somewhat complex example, so I don't have a reproducible piece of code yet, but figured I'd ask first if there were any known issues. – dsh Mar 10 '15 at 00:08
  • This approach does not work with `layer_bars()`. In that case it gives the following: `Error in eval(expr, envir, enclos) : object 'id' not found`. Any idea what to do in that case? (E.g. you would like to plot the counts and tooltip the shares). – janosdivenyi Dec 01 '15 at 15:07
2

One workaround is to pass the epid variable in the key property, which is normally meant to keep track of which observations correspond to one another during transitions but it has the desired effect here of including epid in the data without producing any side effects:

breakingbad.episodes <- data.frame(firstaired.posix = as.POSIXct(c("2008-01-21 02:00:00", "2008-01-28 02:00:00")),
rating = c(87, 85), epid = as.factor(c(12,23)), season = as.factor(c(1,2)), somevar = c("special", "very_special"))

breakingbad.episodes %>% 
  ggvis(x = ~firstaired.posix, 
        y = ~rating, 
        fill = ~season, key := ~epid) %>% 
  layer_points() %>%
  add_axis("x", title = "Airdate") %>%
  add_axis("y", title = "Rating") %>%
  add_legend("fill", title = "Season") %>%
  add_tooltip(function(data){paste0("Rating: ", data$rating, "\n", "Epid: ", as.character(data$epid))}, "hover")

If you needed to use multiple variable from the original dataset you can add an id column with a unique value for each row and then do this:

breakingbad.episodes <- data.frame(id = c(1,2), firstaired.posix = as.POSIXct(c("2008-01-21 02:00:00", "2008-01-28 02:00:00")),
rating = c(87, 85), epid = as.factor(c(12,23)), season = as.factor(c(1,2)), somevar = c("special", "very_special"))

breakingbad.episodes %>% 
  ggvis(x = ~firstaired.posix, 
        y = ~rating, 
        fill = ~season, key := ~id) %>% 
  layer_points() %>%
  add_axis("x", title = "Airdate") %>%
  add_axis("y", title = "Rating") %>%
  add_legend("fill", title = "Season") %>%
  add_tooltip(function(data){paste0("Rating: ", data$rating, "\n", "Epid: ",
as.character(breakingbad.episodes$epid[breakingbad.episodes$id == data$id]), "\n", 
"What this is: ", breakingbad.episodes$somevar[breakingbad.episodes$id == data$id])}, "hover")
ecologician
  • 473
  • 3
  • 9