Search code examples
rggvis

R ggvis: sliderInput for fontSize


I am struggling to make a ggvis plot where the font size of the X-axis text would be controlled by a slider. Now I am getting the following warning:

Warning message:
In toJSON(unclass(x), container, collapse, ..., .level = .level +  :
  converting an R function to JSON as null. To change this, define a method for toJSON() for a 'function' object.

Here is the code:

mivector<-c(1.5,2,2.5,2,2.5,3,2.5,3,3.5)
treats<-c("A","A","A","B","B","B","C","C","C")

library(ggvis)
library(dplyr)

plotdf<-data.frame(mivector,treats)

plotdf %>% ggvis() %>% layer_points(x=~treats,y=~mivector) %>% 
  add_axis("y",grid=F,title="") %>% 
  add_axis("x",grid=F,title="",properties=axis_props(labels=list(fontSize=input_slider(min=8,max=20,value=14,label="Font size of the X-axis text"))))

I will be very grateful for your help!


Solution

  • There is no way you can do that currently with ggvis.

    When ggvis is plotting, three different types of messages is sent to your browser.

    1. Plot specifications (width, height, axis ticks, labels and axis font sizes etc)
    2. Plot data (points, lines, their colors, opacity etc.)
    3. A ggvis command. Currently there is only one: update.

    Although ggvis allows you to create interactive plots, it is important to keep in mind that you can only update the data in (2). ( once you update the data in (2), (3) is implied automatically ).

    The plot specifications in (1), however, is packed in a JSON object and send your browser only once when the plot is initiated. You can read this post from ggvis's author about this.

    That means, all plot specifications that you want to specify must be JSON-serializable. Functions, can't be packed into JSON (unless, as the warning specified, define a method for toJSON() for a function object).

    A slider created by input_slider() is a function: (more precisely, a reactive variable, which is a function itself),

    > slider <- input_slider(min=8,max=20,value=14,label="Font size of the X-axis text")
    > typeof(slider)
    [1] "closure"
    

    hence it can't be part of the plot specifications.


    Solution

    You can't solve your problem in ggvis alone. But you can address this issue by using Shiny. You can check out this tutorial for Shiny. Also, See this article for how you can integrate a ggvis plot into a Shiny application.

    In short, you will have to:

    • Create a sliderInput in Shiny (similar to input_slider in ggvis) that is used to specify the x-axis font size. This part goes into the ui.R of a Shiny application.
    • Create a ggvisOutput object in ui.R.
    • In server.R, wrap your ggvis plotting expressions in a reactive environment, in which you can let the fontSize equal to the value from the sliderInput.

    The trick here is to wrap your ggvis call in a reactive environment. Therefore, every time the slider input changes, the reactive environment is re-evaluated, hence the ggvis function is called again, and the ENTIRE plot is redrawn. (Remember the 1. 2. 3. stages of ggvis? They will all be updated because literally you make a new ggvis function call every time you changes your slider input).