Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can't get interactive zooming to work with ggvis

Tags:

r

ggvis

I'm trying to get interactive zooming to work in ggvis, more in particular zooming using a brush. Judging from https://github.com/rstudio/ggvis/issues/143 I thought this should work.

I have the following shiny and ggvis code (is fully reproducible):

## ui.R
library(ggvis)

shinyUI(fluidRow(
  uiOutput('ui_plot1'),
  ggvisOutput("graph_plot1")
))

## server.R
shinyServer(function(input, output, session) {
  domains <- reactiveValues(x = c(NA, NA), y = c(NA, NA))

  zoom_brush = function(items, session, page_loc, plot_loc, ...) {
    domains$x = c(200, 400)
  }

  plot = reactive({
    mtcars %>% 
      ggvis(~disp, ~mpg) %>%
      layer_points() %>%
      scale_numeric('x', domain = domains$x, clamp = TRUE) %>% 
      handle_brush(zoom_brush)
  }) %>% bind_shiny('graph_plot1', 'ui_plot1')
})

So, as soon as a brush is drawn, the domains reactive is changed, which in turn changes the domain of the x scale_numeric. If still have the following challenges:

  • Inside zoom_brush I get the coordinates of the brush, but in the pixel coordinate system of the plot not the domain coordinate system. How can I translate the pixels to the domain scale? In d3 I can simply use the range to scale transform functions, but I don't see how these are available in ggvis (via vega).
  • The handle_brush function only supports setting a on_move event handler. In this case I only want to trigger the zoom if the brush finishes, so the onmouseup event in the context of the brush. I fear that this is simply not possible right now?
  • Only when I set clamp = TRUE do I get an effective zoom. In not, the points outiside the domain are still shown and only the axes are set to the new domain. Is there an easy fix for this? Or should I make the dataset a reactive, and subset it based on the domain that was set by the brush?

I run the following R version and package versions.

> sessionInfo()
R version 3.1.1 (2014-07-10)
Platform: x86_64-apple-darwin10.8.0 (64-bit)

locale:
[1] C

attached base packages:
[1] stats     graphics  grDevices utils     datasets  methods   base     

other attached packages:
[1] ggvis_0.4.1  shiny_0.12.0

loaded via a namespace (and not attached):
 [1] DBI_0.3.1       R6_2.0.1        Rcpp_0.11.6     assertthat_0.1  digest_0.6.8    dplyr_0.4.1     htmltools_0.2.6 httpuv_1.3.2   
 [9] jsonlite_0.9.16 lazyeval_0.1.10 magrittr_1.5    mime_0.3        parallel_3.1.1  tools_3.1.1     xtable_1.7-4   
like image 974
Paul Hiemstra Avatar asked Sep 14 '15 16:09

Paul Hiemstra


1 Answers

I think you need to subset your data: ggvis doesn't yet appear clever enough to ignore out of scale points. The following server.R works for me:

## server.R
shinyServer(function(input, output, session) {

  domains <- reactiveValues(x = c(NA, NA), y = c(NA, NA))

  mtcars_reactive <- reactive({
    if (anyNA(domains$x))
      mtcars
    else
      mtcars[mtcars$disp >= domains[["x"]][1] & mtcars$disp <= domains[["x"]][2], ]
  })

  zoom_brush = function(items, page_loc, session, ...) { # plot_loc
    print(items)
    message("page_loc")
    print(page_loc)
    print(session)
    domains$x = c(200, 400)
  }

  reactive({
    mtcars_reactive() %>%
      ggvis(~disp, ~mpg) %>%
      layer_points() %>%
      handle_brush(zoom_brush)
  }) %>% bind_shiny('graph_plot1', 'ui_plot1')

})
like image 175
Jack Wasey Avatar answered Sep 28 '22 03:09

Jack Wasey