4

I've been playing around with the nice ggvis package. I'm doing a custom linear regression and wanted a tooltip to show info about each data point. However, when I add my regression line, the tooltip appears when I hover over the line, and shows then the info about the first datapoint (see screenshot). I provide this simple reproducible example:

library(ggvis)
mtc <- mtcars
lm=with(mtc,lm(mpg~wt))
mtc$fit=lm$coefficients[1]+mtcars$wt*lm$coefficients[2]
mtc$id <- 1:nrow(mtc)  # Add an id column to use ask the key

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

mtc %>% ggvis(x = ~wt, y = ~mpg, key := ~id) %>%
    layer_points() %>%layer_lines(x= ~wt,y= ~fit)%>% 
    add_tooltip(all_values, "hover")

This produces thisenter image description here

I would like to exclude the regression line from the tooltip so it only shows info about the data points. Is there a way to achieve this? Thank you for your help!

LyzandeR
  • 37,047
  • 12
  • 77
  • 87
Sölvi
  • 500
  • 5
  • 17

1 Answers1

3

After a bit of playing around I got it to work.

First of all I needed to construct two separate data sets for this to work. One for the linear model data and one for the mtcars.

Solution

Constructing the data

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

lm=with(mtc,lm(mpg~wt))
df=data.frame(fit=lm$coefficients[1]+mtcars$wt*lm$coefficients[2])
df$id <- 101:132
df$wt <- mtcars$wt

As you can see above mtc is the data with the mtcars data and df is the linear model data. Notice that in the df I added an id column all of its values are greater than 100 and also completely different to the mtc data.frame.

Whenever you hover over points all_values will access the id column from mtc and whenever you hover over the line all_values will access the id column from df.

I added a line to your function below which is what makes it work:

all_values <- function(x) {
  #if the id is greater than 100 i.e. the df data.frame
  #then return NULL
  if(x$id>100) return(NULL)
  if(is.null(x)) return(NULL)
  row <- mtc[mtc$id == x$id, ]
  paste0(names(row), ": ", format(row), collapse = "
           ")
}

Then plot two separate data.frames. the add_tooltip will find the id variable for for both data.frames:

ggvis(x=~wt) %>%
     layer_points(data=mtc, y = ~mpg, key := ~id) %>%
     layer_paths(data=df,y= ~fit, key := ~id) %>%
     add_tooltip(all_values, "hover")

I cannot show the full interactivity with this graph but you can see in the pic below that although my cursor is above the line no info is shown.

enter image description here

Whereas the points do show the info when hovered over.

enter image description here

Community
  • 1
  • 1
LyzandeR
  • 37,047
  • 12
  • 77
  • 87
  • 2
    Nice workaround. I had to do something similar once in a Shiny app; not very elegant. Hadley and Winston have this feature in the pipeline: https://groups.google.com/forum/#!topic/ggvis/ktlFHhYcORM – Steven Beaupré Jul 05 '15 at 13:37
  • Works perfectly! What is the reason for the use of layer_paths() instead of layer_lines? Also, does the df data fame require an id, that is, is the all_values function applied on every layer of the ggvis plot? – Sölvi Jul 05 '15 at 13:43
  • @StevenBeaupré oh great thanks! Good to know about it :) – LyzandeR Jul 05 '15 at 13:57
  • 1
    @Sölvi I used `layer_paths` because it works great with multiple data sets. `layer_lines` seems to fail with that. As for the id column in the df data.frame, maybe it doesn't necessarily require it. When you hover over the line, `x` in `all_values` becomes `df`. So you can use which ever value/column in the if condition to make it return NULL. You need to use a condition though otherwise `all_values` will fail. You had used an id for the mtc data.frame so it made sense for me to use the same :) – LyzandeR Jul 05 '15 at 14:02