Tag Archives: GUI

Comparing Shiny with gWidgetsWWW2.rapache

(A guest post by John Verzani)

A few days back the RStudio blog announced Shiny, a new product for easily creating interactive web applications (http://www.rstudio.com/shiny/). I wanted to compare this new framework to one I’ve worked on, gWidgetsWWW2.rapache – a version of the gWidgets API for use with Jeffrey Horner’s rapache module for the Apache web server (available at GitHub). The gWidgets API has a similar aim to make it easy for R users to create interactive applications.

I don’t want to worry here about deployment of apps, just the writing side. The shiny package uses websockets to transfer data back and forth from browser to server. Though this may cause issues with wider deployment, the industrious RStudio folks have a hosting program in beta for internet-wide deployment. For local deployment, no problems as far as I know – as long as you avoid older versions of internet explorer.

Now, Shiny seems well suited for applications where the user can parameterize a resulting graphic, so that was the point of comparison. Peter Dalgaard’s tcltk package ships with a classic demo tkdensity.R. I use that for inspiration below. That GUI allows the user a few selections to modify a density plot of a random sample.

gWidgetsWWW2

We’ll start with a gWidgets approach and work our way to the shiny code. A basic GUI can be generated with the following code:

?View Code RSPLUS
 
width <- 600; height <- 480
 
## The plot commands. Uses GUI objects defined below
make_plot <- function(...) {
  y <- get(svalue(distribution))(svalue(size))
  plot(density(y, bw=svalue(bandwidth)/100, kernel=svalue(kernel)))
  points(y, rep(0, svalue(size) ))
}
 
update_plot <- function(...) {
  f <- tempfile()
  require(canvas)
  canvas(f, width=width, height=height)
  make_plot()
  dev.off()
  svalue(cnv) <- f ## update canvas widget
}
 
## The layout
w <- gwindow("tkdensity example")
gstatusbar("Powered by gWidgetsWWW2.rapache and rapache", cont=w)
 
## containers
bl <- gborderlayout(cont=w)
fl <- gformlayout(cont=bl, where="west")
 
## controls
distribution <- gcombobox(data.frame(value=c("rnorm", "rexp"),
                                     labels=c("Normal", "Exponential"),
                                     stringsAsFactors=FALSE),
                          cont=fl, label="distribution")
kernel <- gcombobox(c("gaussian", "epanechnikov", "rectangular",
             "triangular", "cosine"),
                    cont=fl, label="kernel")
size <- gcombobox(c(5,50, 100, 200, 300),
                  coerce.with="as.numeric",
                  cont=fl, label="size")
bandwidth <- gslider(0.05*100, 2*100, by=0.05*100, value=1*100,
                     width=250,
                     coerce.with="as.numeric",
                     cont=fl, label="bandwidth")
refresh <- gbutton("refresh",
                   cont=fl, label="")
 
cnv <- gcanvas(cont=bl, where="center", width=width, height=height)
 
## connect controls
for(i in list(kernel, size, bandwidth, refresh))
  addHandlerChanged(i, update_plot)

All right, that may look like a lot, but lots of people have used gWidgets to write such GUIs. They aren’t that hard. basically there are three parts:

  • The definition of the controls and their layout that comprise the
    user interface.
  • The definition of some callback to create the graphic when a control
    is updated.
  • Some means to specify when to invoke this call back.

The gWidgets API is meant to be cross-toolkit, but this is only mostly true. In the above we use a few web-specific features, including the canvas package to provide a JavaScript canvas for drawing R graphics.

Manipulate

This particular example would be really easy were we able to use RStudio’s manipulate package. That is only for RStudio users though. Well, not really. There is a simple map available in the gWidgetsWWW2.rapache package that allows us to easily use that specification. Here is the code:

?View Code RSPLUS
 
## load in map for manipulate -> gWidgets
source(system.file("demo", "manipulate.R", package="gWidgetsWWW2.rapache"), local=TRUE)
 
w <- gwindow("Manipulate example")
gstatusbar("Powered by gWidgetsWWW2.rapache and rapache", cont=w)
 
manipulate(
           {
             y <- get(distribution)(size)
             plot(density(y, bw=bandwidth/100, kernel=kernel))
             points(y, rep(0, size))
           },
           ##
           distribution=picker("Normal"="rnorm", "Exponential"="rexp"),
           kernel=picker("gaussian", "epanechnikov", "rectangular",
             "triangular", "cosine"),
           size=picker(5, 50, 100, 200, 300),
           bandwidth=slider(0.05 * 100, 2.00 * 100, step=0.05 * 100, initial=1* 100), # integers needed
           button=button("Refresh"),
           ## gWidgetsWWW2.rapache extras
           container=w,       
           device="svg",                # svg or canvas or png
           delay=1000                   # delay to let data load for combo boxes
           )

Okay, I admit. I’m a fan of manipulate and it really is a perfect way to specify an interface as straightforward as this. This one is an example in the gWidgetsWWW2.rapache package and you can see it in action at http://www.math.csi.cuny.edu/gw/ex-manipulate.R (though this redirects to a private server which is often not online). The manipulate interface handles the layout of the controls and the invocation of the callback, all you add is an expression to plot and a specification of
the controls.

Shiny

Now for Shiny. We noted above there are really three pieces to writing this app, with Shiny we only need to worry about two: the definition and layout of the user interface, and the specification of how the resulting graphic is made. For this, we write two functions: ui.R and server.R.

The ui.R files is used to layout the interface. Here is ours:

?View Code RSPLUS
library(shiny)
 
shinyUI(pageWithSidebar(
 
  # Application title
  headerPanel("tkdensity"),
 
  # Sidebar with a slider input for number of observations
  sidebarPanel(
               selectInput("distribution", "Distribution:", 
                           choices = c("Normal"="rnorm", "Exponential"="rexp")),
               selectInput("kernel", "Kernel:", 
                           choices = c("gaussian", "epanechnikov", "rectangular",
                             "triangular", "cosine")),
               selectInput("size", "Size:", 
                           choices = c(5,50, 100, 200, 300)),
               sliderInput("bandwidth", "bandwidth:", 
                           min = 0.05, 
                           max = 2, 
                           value = 1)
  ),
 
  # Show a plot of the generated distribution
  mainPanel(
    plotOutput("distPlot")
  )
))

There are a few containers (“panels”) and a few controls specified (“inputs”). The basic usage of shiny involves just a handful of each and they are easy to learn. The above code simply makes a header, puts four controls into a side panel and in the main panel readies a place to display our plots. The name distPlot is odd because I stole this basic set up from one of shiny‘s examples and made just minor changes.

The server.R file is not difficult either. We need to make the graphic so that it displays. Here it is:

?View Code RSPLUS
library(shiny)
 
shinyServer(function(input, output) {
 
  make_plot <- function(distribution, size, bandwidth, kernel) {
    y <- get(distribution)(size)
    plot(density(y, bw=bandwidth, kernel=kernel))
    points(y, rep(0, size))
  }
 
  output$distPlot <- reactivePlot(function() {
    make_plot(input$distribution, input$size, input$bandwidth, input$kernel)
  })
})

Again, this is only slightly modified from an example. The input object is not a list or an environment, but we can extract the values associated with the user interface as though it were. In the above we see the distributionsizebandwidth and kernel values are passed along to the make_plot call. The only new thing here, besides that, is the magic way we create a plot (passing a function as a call back to reactivePlot and assigning it to distPlot in the output object). The shiny package takes care of the third part of our GUI, using this “reactive” programming style to synchronize various parts of
the interface.

Want to see it at work? Well fire up your copy of shiny and run it from a GitHub gist:

?View Code RSPLUS
require(shiny)
shiny:::runGist("4009017")

Before you gloss over the above lines, think how neat this is. Just as you can install packages from GitHub within an R session through the devtools package, you can run shiny apps within R from GitHub with the runGist function. This is an awesome feature for deploying interactive web apps for local usage.

I think you’ll see, if you compare, for this task the user experience is nicer with shiny than that of gWidgetsWWW2.rapache. The specification of the GUI is easiest with the manipulate style, but using shiny wasn’t difficult. I personally like very much the use of the “bootstrap” CSS libraries (http://twitter.github.com/bootstrap/), as opposed to the ExtJS CSS (http://www.sencha.com/products/extjs/). The interface looks very modern. (Not only looks, the slider is much better than that in gWidgetsWWW2.rapache, where the underlying control only wants integer values.) Though the gWidgetsWWW2.rapache package might have more controls and more layout options than the basic use of shiny, I can see that there will be a huge number of great shiny apps written. Within its range of use, it is a great choice for easily making R-driven web applications.

About:

John Verzani is the maintainer of the gWidgets set of packages and co-author with Michael Lawrence of the book Programming Graphical User Interfaces in R.

Rose plot using Deducers ggplot2 plot builder

The (excellent!) LearnR blog had a post today about making a rose plot in
ggplot2.

Following today’s announcement, by Ian Fellows, regarding the release of the new version of Deducer (0.4) offering a strong support for ggplot2 using a GUI plot builder, Ian also sent an e-mail where he shows how to create a rose plot using the new ggplot2 GUI included in the latest version of Deducer. After the template is made, the plot can be generated with 4 clicks of the mouse.

Here is a video tutorial (Ian published) to show how this can be used:

The generated template file is available at:
http://neolab.stat.ucla.edu/cranstats/rose.ggtmpl

I am excited about the work Ian is doing, and hope to see more people publish use cases with Deducer.

ggplot2 plot builder is now on CRAN! (through Deducer 0.4 GUI for R)

Ian fellows, a hard working contributer to the R community (and a cool guy), has announced today the release of Deducer (0.4) to CRAN (scheduled to update in the next day or so).
This major update also includes the release of a new plug-in package (DeducerExtras), containing additional dialogs and functionality.

Following is the e-mail he sent out with all the details and demo videos.

Read more »

The new GUI for ggplot2 (using Deducer) – the designer wants your opinion

After discovering that R is expected (this summer) to have a GUI for ggplot2 (through deducer), I later found Ian’s gsoc proposal for this GUI.  Since the system is in it’s early stages of development, Ian has invited people to give comments, input and critique on his plans for the project.

For your convenience (and with Ian’s permission), I am reposting his proposal here. You are welcome to send him feedback by e-mailing him (at: [email protected]), or by leaving a comment here (and I will direct him to your comment).

Read more »

R is going to have a GUI to ggplot2! (by the end of this years google-summer-of-code)

I was delighted to see the following e-mail post from Dirk Eddelbuettel regarding the google-summer-of-code R google group:
* * *

Earlier today Google finalised student / mentor pairings and allocations for
the Google Summer of Code 2010 (GSoC 2010). The R Project is happy to
announce that the following students have been accepted:

Colin Rundel, “rgeos – an R wrapper for GEOS”, mentored by Roger Bivand of
the Norges Handelshoyskole, Norway

Ian Fellows, “A GUI for Graphics using ggplot2 and Deducer”, mentored by
Hadley Wickham of Rice University, USA

Chidambaram Annamalai, “rdx – Automatic Differentiation in R”, mentored by
John Nash of University of Ottawa, Canada

Yasuhisa Yoshida, “NoSQL interface for R”, mentored by Dirk Eddelbuettel,
Chicago, USA

Felix Schoenbrodt, “Social Relations Analyses in R”, mentored by Stefan
Schmukle, Universitaet Muenster, Germany

Details about all proposals are on the R Wiki page for the GSoC 2010 at
http://rwiki.sciviews.org/doku.php?id=developers:projects:gsoc2010

The R Project is honoured to have received its highest number of student
allocations yet, and looks forward to an exciting Summer of Code. Please
join me in welcoming our new students.

At this time, I would also like to thank all the other students who have
applied for working with R in this Summer of Code. With a limited number of
available slots, not all proposals can be accepted — but I hope that those
not lucky enough to have been granted a slot will continue to work with R and
towards making contributions within the R world.

I would also like to express my thanks to all other mentors who provided for
a record number of proposals. Without mentors and their project ideas we
would not have a Summer of Code — so hopefully we will see you again next
year.

Regards,

Dirk (acting as R/GSoC 2010 admin)

* * *

From all the projects, the one I am most excited about is:
Ian Fellows, “A GUI for Graphics using ggplot2 and Deducer”, mentored by Hadley Wickham of Rice University, USA

Deducer (text from the website) attempts to be a free easy to use alternative to proprietary data analysis software such as SPSS, JMP, and Minitab. It has a menu system to do common data manipulation and analysis tasks, and an excel-like spreadsheet in which to view and edit data frames. The goal of the project is to two-fold.

  • Provide an intuitive interface so that non-technical users can learn and perform analyses without programming getting in their way.
  • Increase the efficiency of expert R users when performing common tasks by replacing hundreds of keystrokes with a few mouse clicks. Also, as much as possible the GUI should not get in their way if they just want to do some programming.

Deducer is designed to be used with the Java based R console JGR, though it supports a number of other R environments (e.g. Windows RGUI and RTerm).

This combination (of Deducer and ggplot2) might finally provide the bridge to the layman-statistician that some people recently wrote to be one of R’s weak spots (while other bloogers wrote back that this is o.k., still no one refuted that R doesn’t compete with the point-and-click of softwares like SPSS or JMP.)
I came across Ian in the discussion forums, where he provided very kind help to his package “deducer”. Coupled with having Hadley as his mentor, I am very optimistic about the prospects of seeing this project reaching very high standards.
Very exciting development indeed!

Update: Ian’s proposal is available to view here.

p.s: for some intuition about how a GUI for ggplot2 can look like, have a look at this video of Jeroen Ooms’s ggplot2 web interface