Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
255 views
in Technique[技术] by (71.8m points)

r - How is data passed from reactive Shiny expression to ggvis plot?

I am getting acquainted with ggvis and I am trying to use it in shiny. I am having trouble understanding how ggvis gets the data from the reactive Shiny expression. Here is the basic app from ggvis GitHub repository:

ui.R:

shinyUI(pageWithSidebar(
  div(),
  sidebarPanel(
    sliderInput("n", "Number of points", min = 1, max = nrow(mtcars),
                value = 10, step = 1),
    uiOutput("plot_ui")
  ),
  mainPanel(
    ggvisOutput("plot"),
    tableOutput("mtc_table")
  )
))

server.R:

library(ggvis)

shinyServer(function(input, output, session) {
  # A reactive subset of mtcars
  mtc <- reactive({ mtcars[1:input$n, ] })

  # A simple visualisation. In shiny apps, need to register observers
  # and tell shiny where to put the controls
  mtc %>%
    ggvis(~wt, ~mpg) %>%
    layer_points() %>%
    bind_shiny("plot", "plot_ui")

  output$mtc_table <- renderTable({
    mtc()[, c("wt", "mpg")]
  })
})

Now mtc is the reactive expression which is actually a function (or is it?), Its result is a data.frame. However it is piped to ggvis as a function. If you tried to pass the resulting data.frame like

mtc() %>%  ggvis(~wt, ~mpg) %>%
layer_points() %>%
        bind_shiny("plot", "plot_ui")

Shiny would start complaining along the lines that "Operation not allowed without an active reactive context". So what is actually going on?

The reason I am asking is that I would like to return additional objects which I want to use in ggvis. To be more precise I want to change x and y axis labels, where the labels are computed inside in the reactive expression, something like this:

mtc <- reactive({ list(data=mtcars[1:input$n, ],
labx = "Computed x axis label",
laby = "Computed y axis label")
   })

mtc %>% ggvis(data=data,~wt,~mpg) %>% 
    layer_points() %>%
    add_axis("x",title=labx) %>%
    add_axis("y",title=laby) %>%
    bind_shiny("plot", "plot_ui")

Is it possible to somehow exploit the structure of mtc() output inside of ggvis call? Or it is only possible to pass the data.frame and then put your data in the data.frame?

Or is there another way to register ggvis object? In this question the ggvis output is registered with observe_ggvis function, but it seems that it is not present in current ggvis version (0.3).

I am using ggvis version 0.3.0.1 and shiny 0.10.0 on R 3.1.1

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

ggvis can be passed "bare reactives" for a dataset. When you do this ggvis will automatically replot the data when it changes but it doesn't need to replot the entire plot:

get_rct_df = reactive({  #code to change dataset from shiny input  )}
get_rct_df %>% ggvis() #rest of plotting code %>% bind_shiny("plot")

This will update the data points in the plot (but not redraw the entire plot) each time the data from get_rct_df changes. This also means that certain things cannot be updated without redrawing the entire plot (plot labels, equations for layer_model_predictions).

You can do the other suggestion and wrap the entire plot in a reactive:

reactive({
   get_rct_df %>% 
      ggvis() #rest of plotting code %>% 
      add_axis("x", title = input$title)
}) %>% bind_shiny("plot")

This will allow you to update plot titles and other parts of the plot. But it also forces ggvis to replot the entire plot when something changes as opposed to just replotting the data. If you test out both methods, method 1 will look "smoother"; ggvis has built in transition animations when you data changes.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

1.4m articles

1.4m replys

5 comments

56.9k users

...