Skip to content

Instantly share code, notes, and snippets.

@jverzani
Created November 3, 2012 22:02
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save jverzani/4009017 to your computer and use it in GitHub Desktop.
Some comparisons using shiny and gWidgetsWWW2

RStudio developers are really hard working. Somehow in their spare time they have worked on their shiny package for making interactive web pages. This gist compares writing a shiny web app to writing a similar app using gWidgetsWWW2.rapache. We only look here at the code, not the deployment. In general, deploying a shiny app widely seems best suited for RStudio's service, currently in beta, though clearly a local shiny app is also quite useful. Deploying an app under gWidgetsWWW2.rapache is fairly easy -- though not very widely tested.

We follow the tkdensity.R GUI from the tcltk package for comparison. This is a standard example with some controls and a resulting graphic. It is right up shiny's alley. We compare to the manipulate commands which mimic RStudio's manipulate pacakge and to straight gWidgetss:

There are 4 files:

  • a file showing how to do this with manipulate (this is an example from the gWidgetsWWW2.rapache package)
  • a file showing gWidgetsWWW2.rapache style (both have a workaround for the need to have integer values for a slider)
  • two files for shiny (both quick modifications of one of the examples)

Clearly the manipulate code is easiest, but that is the most limited framework. I have to say shiny comes in second and not a distant one. It also looks better, as the bootstrap CSS seems more modern to me than that for extjs. To run the shiny app here you have only to execute: shiny:::runGist("4009017"). The manipulate example is at http://www.math.csi.cuny.edu/gw/ex-manipulate.R (though this runs on a private server which is often not online). As for gWidgetsWWW2.rapache this is maybe a more flexible framework than shiny. One could argue this point, but certainly it has more flexibility for a non-web programmer.

## http://rstudio.org/docs/advanced/manipulate
## example from tkdensity.R
## This is an example of the manipulate function
## that is provided in RStudio. Here we implement our
## own version using the code from this package. The
## basics are read in here. We need local=TRUE
source(system.file("demo", "manipulate.R", package="gWidgetsWWW2.rapache"), local=TRUE)
## this is an example usage. The idea comes from the tkdensity.R demo
## in the tcltk package.
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"),
##
container=w,
device="svg", # svg or canvas or png
delay=1000 # delay to let data load for comboboxes
)
library(shiny)
# Define server logic required to generate and plot a random distribution
shinyServer(function(input, output) {
# Function that generates a plot of the distribution. The function
# is wrapped in a call to reactivePlot to indicate that:
#
# 1) It is "reactive" and therefore should be automatically
# re-executed when inputs change
# 2) Its output type is a plot
#
make_plot <- function(distribution, size, bandwidth, kernel) {
y <- get(distribution)(size)
plot(density(y, bw=bandwidth, kernel=kernel))
points(y, rep(0, size))
}
## reactivePlot wants a function
output$distPlot <- reactivePlot(function() make_plot(input$distribution, input$size, input$bandwidth, input$kernel))
})
library(shiny)
# Define UI for application that plots random distributions
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")
)
))
w <- gwindow("tkdensity example")
gstatusbar("Powered by gWidgetsWWW2.rapache and rapache", cont=w)
width <- 600; height=480
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
}
bl <- gborderlayout(cont=w)
fl <- gformlayout(cont=bl, where="west")
distribution <- gcombobox(data.frame(value=c("rnorm", "rexp"),
labels=c("Normal", "Exponential"),
stringsAsFactors=FALSE),
cont=fl, label="distribution",
handler=update_plot
)
kernel <- gcombobox(c("gaussian", "epanechnikov", "rectangular",
"triangular", "cosine"),
cont=fl, label="kernel",
handler=update_plot)
size <- gcombobox(c(5,50, 100, 200, 300),
coerce.with="as.numeric",
cont=fl, label="size",
handler=update_plot)
bandwidth=gslider(0.05*100, 2*100, by=0.05*100, value=1*100,
width=250,
coerce.with="as.numeric",
cont=fl, label="bandwidth",
handler=update_plot)
refresh <- gbutton("refresh",
cont=fl, label="",
handler=update_plot
)
cnv <- gcanvas(cont=bl, where="center", width=width, height=height)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment