This page will be used during the presentation at the Meetup for “Interactive Visualization and Publishing Data using R (ggvis and rCharts)” on July 23rd at 6:30PM, as well as on August 20th, at 6:30PM (when the Meetup is continued)

Below is the R code, so you can copy and paste during the presentation.

Prepare tools to publish the visualizations

Other preparation for the Meetup

Get ready for the meeting (optional): While this is optional, come a little early if you do not have it installed so we can get started on time.

  1. Download and Install R: http://cran.wustl.edu/ It may be best to have the latest version of R (or at least 3.0.3), for all libraries to work properly

  2. Download and install R-Studio from this web link: https://www.rstudio.com/ide/

  3. Install ggvis from within R (or R-Studio), execute the following two lines of code:

install.packages("devtools")
devtools::install_github(c("rstudio/shiny", "rstudio/ggvis"), build_vignettes = FALSE)
  1. You can install rCharts from github using the devtools package (see more info here: http://ramnathv.github.io/rCharts/)
require(devtools)
install_github('rCharts', 'ramnathv')

NOTE: the installation steps above will save you time during the meeting. If you have any problems or issues with the installation please let us know.

Brief Outline of Meetup

Presentation Material

A little about ggvis

  • ggvis is a data visualization package, developed by Hadley Wickham, which allows for interactive graphics thanks to shiny integration

  • ggvis is perfect for exploratory data analysis
  • syntax is similar to ggplot2
  • works great with dplyr
  • graphics can be published online using shiny
  • Installing. Now available on CRAN:

install.packages("ggvis")

or install the development package:

install.packages("devtools") devtools::install_github("rstudio/ggvis", build_vignettes = FALSE)

Working with ggvis

Load ggvis

library(ggvis)

Simple call to ggvis (courtesy of http://ggvis.rstudio.com/cookbook.html)

library(ggvis)
p<- ggvis(mtcars, x = ~wt, y = ~mpg)
layer_points(p) # To actually plot (display) the data

Below is a static image of the plot

Use ‘pipe’* - %>% - to avoid nested functions and “temporary” variables. %>% takes value on the left-hand side and passes it to function or expression on the right-hand side. Comes from magrittr package.

library(ggvis)
mtcars %>%
ggvis(x = ~wt, y = ~mpg) %>%
layer_points()

Below is a static image of the plot

Hands-On Example

First download the data into a data folder in your working directory, for example:

This will work on a Windows machine. You’re basically creating a “data” folder in your working directory and downloading the files into it.

if(!file.exists("./data")){dir.create("./data")}
reportsUrl <- "https://github.com/ConnieZ/ufo_app/raw/master/data/ufo_reports.csv"
download.file(reportsUrl, destfile="./data/ufo_reports.csv", mode="wb")
milbaseUrl <- "https://github.com/ConnieZ/ufo_app/raw/master/data/milbases.csv"
download.file(milbaseUrl, destfile="./data/milbases.csv", mode="wb")

This will work on a Mac/Linux machine. You’re basically creating a “data” folder in your working directory and downloading the files into it, but at the same time you have the data sets in your memory, so you don’t have to read.csv() again.

if(!file.exists("./data")){dir.create("./data")}

#Download files for mac
library(RCurl)
reportsUrl <- getURL("https://raw.githubusercontent.com/ConnieZ/ufo_app/master/data/ufo_reports.csv")
reports <- read.csv(text=reportsUrl)
write.csv(reports, "./data/ufo_reports.csv")

milbaseUrl <- getURL("https://raw.githubusercontent.com/ConnieZ/ufo_app/master/data/milbases.csv")
milbases <- read.csv(text=milbaseUrl)
write.csv(milbases, "./data/milbases.csv")
# merge the data sets
mergeddata <- merge(reports, milbases, by="State")

Merge the data in the data folder (the below is for Windows users that followed the code above):

setwd("C:/Users/kanstantsyia/Documents") #this is to point Rmd to the right directory for data files. Use appropriate location in your code.
milbases <- read.csv("data/milbases.csv")
reports <- read.csv("data/ufo_reports.csv")
mergeddata <- merge(reports, milbases, by="State")

Create the plot:

library(ggvis)
mergeddata %>% 
ggvis( ~Total, ~UFOReports) %>% 
layer_points(fill = ~UFOReports, size := input_slider(10, 100, label = "Point Size")) %>%
layer_model_predictions(model = input_radiobuttons( choices = c("Linear" = "lm", "LOESS" = "loess"), selected = "lm",
label = "Model type"), se = TRUE) %>%
add_axis("y", title = "Num of UFO Reports", orient = "left", title_offset = 50)

Below is a static image of the plot

Publishing ggvis charts online

Steps:

Create ui.R and server.R files for a Shiny app in a certain folder (folder name = short name of your app). Copy the data folder from your working directory that contains the downloaded files into the app folder.

For our hands-on example we also added tooltips to the plot. Within the folder with the server.R and ui.R files, which we called “app_ggvis_demo”, is also a data folder with the csv files for the chart.

Below is the server.R file

# server.R

library(ggvis)

#data reading and manipulations
milbases <- read.csv("data/milbases.csv")
reports <- read.csv("data/ufo_reports.csv")
mergeddata <- merge(reports, milbases, by="State")
mergeddata$id <- 1:nrow(mergeddata)

#function to connect a data point to its other variabless in data set for tooltip
all_values <- function(x) {
  if(is.null(x)) return(NULL)
  row <- mergeddata[mergeddata$id == x$id, ]
  paste0("State", ": ", row$State,"<br />", "UFO Reports", ": ", row$UFOReports,"<br />", "Total Bases", ": ", row$Total, "<br />", "Air Force Bases", ": ", row$AirForce,"<br />")
}

shinyServer(
  function(input, output, session) {
      
      #interactive controls
      input_size <- reactive(input$size)
      input_model <- reactive(input$model)
            
      #ggvis plot build
      mergeddata %>% 
        ggvis( x = ~Total, y = ~UFOReports) %>% 
        layer_points(fill := "blue", size := input_size, key := ~id) %>%
        add_tooltip(all_values, "hover") %>%
        layer_model_predictions(model = input_model, se = TRUE) %>%
        add_axis("x", title = "Number of Military Bases", orient = "bottom", title_offset = 50) %>%
        add_axis("y", title = "Num of UFO Reports", orient = "left", title_offset = 50) %>%
        bind_shiny("ggvis", "ggvis_ui")
  }
)

Below is the ui.R file

# ui.R
library(ggvis)
shinyUI(fluidPage(
  titlePanel("UFO Reports (ggvis demo)"),
  
  sidebarLayout(
    sidebarPanel(
      helpText("See the number of UFO reports in relation to 
               the number of military bases by state (USA)."),
      br(),
      helpText("Hover over the data point to see the state and values."),
      
      sliderInput("size", label = "Point Size",min = 10, max = 100, value = 20),
      selectInput("model", label = "Model type", 
                     choices = c("Linear" = "lm", "LOESS" = "loess"),
                     selected = "lm"),
            
      uiOutput("ggvis_ui")
          
    ),
    
    mainPanel(
      
      ggvisOutput('ggvis'))
    )
))

From Rstudio test your application by clicking “Run App” button in your text editor window of Rstudio.

If you have set up your Rstudio with access to Shiny or Shinyapps.io, you will also see the “Deploy” button to publish it online.

Another option:

runApp("myapp")
library(shinyapps)
deployApp("myapp")

See the result here: https://conniez.shinyapps.io/app_ggvis_demo/

More interactivity options for ggvis

Interactive Controls available:

  • input_slider(),
  • input_select() (dropdown menu)
  • input_checkbox(),
  • input_checkboxgroup() (multiple choice),
  • input_radiobuttons(),
  • input_text() and input_numeric() (only numerical input),

Use “=” when assigning interactive controls to a var, “:=” is used only for static values

Other layer options, besides layer_points() and layer_histograms():

  • layer_bars()
  • layer_ribbons() (filled space between two paths or a path and an axis)
  • layer_paths() (all points connected with a line)
  • layer_lines() (equivalent to arrange(x) %>% layer_paths())
  • layer_smooths() (displays predictions with a line)
  • layer_rects() (rectangles)
  • layer_text() (displays text on the chart)

To display multiple layers on one chart - pipe (%>%) them into each other, but include individual parameters (fill, size, span, etc.) inside their parentheses, instead of ggvis()

Some more examples

Example 1 . Run it in your RStudio

library(ggvis)
df <- data.frame(x = 1:12, y = runif(12))
df %>% ggvis(x = ~x, y = ~y, y2 = ~y - 0.1) %>% layer_ribbons() %>%
add_axis("x", title = "Days", orient = "top") %>%
add_axis("y", title = "Quantity Before and After Procedure", orient = "right", title_offset = 50)

Below is the image of the plot

Example 2. Run it in your RStudio

library(ggvis)
ChickWeight %>% 
  ggvis(x = ~Time, y = ~weight, fill = ~factor(Diet)) %>% 
  layer_points() %>% 
  group_by(Diet) %>% 
layer_model_predictions(model="lm", stroke = ~factor(Diet))

Below is the image of the plot

Some more resources on ggvis:

Some More Resources on GGVIS:

Recap of ggvis and some updates:

From the recent RStudio Webinar on July 30, 2014:




A little about rCharts

  • rCharts is an R package to create, customize and publish interactive JavaScript visualizations from R
  • Developed by Ramnath Vaidyanathan, creator of Slidify
  • uses a familiar lattice style plotting interface.
  • R code is converted to JavaScript on the back end, see it when you type
mychart$print()
  • rCharts by itself is interactive to a point, but within a Shiny app it allows input and modification of data in the chart
  • Installation:
require(devtools) 
install_github('rCharts', 'ramnathv') 

Working with rCharts

Load the library, prepare data, create plot as is or assign it to a variable.

library(rCharts)
names(iris) = gsub("\\.", "", names(iris))
r1 <- rPlot(SepalLength ~ SepalWidth | Species, data = iris, color = 'Species', type = 'point')
#r1

Variables above are case sensitive, use the same names as in data set.

rCharts supports multiple javascript charting libraries, each with its own strengths.

Sometimes you may have to to install new packages to take advantage of vast rCharts functionalities (potential error messages will identify that need)

More examples with rCharts

Popular rCharts libraries:

  • Polychart (rPlot() function for basic, but powerful charts, inspired by ggplot2)
  • Morris (mPlot() function for pretty time-series line graphs)
  • NVD3 (nPlot() function based on d3js library for amazing interactive visualizations with little code and customization)
  • xCharts (xPlot() function for slick looking charts using d3js, made by TenXer)
  • HighCharts (hPlot() function interactive charts, time series graphs and map charts)
  • Leaflet (Leaflet$new() function for mobile-friendly interactive maps)
  • Rickshaw (Rickshaw$new() function for creating interactive time series graphs, developed at Shutterstock)

Example 1 (courtesy of http://ramnathv.github.io/rCharts/)

names(iris) = gsub("\\.", "", names(iris))
plot1 <- hPlot(x="SepalLength", y="SepalWidth", type="column", group ="Species", data=iris)
plot1$chart(width = 800)
#plot1

Example 2. Run in your RStudio (courtesy of http://ramnathv.github.io/rCharts/)

library(rCharts)
usp = reshape2::melt(USPersonalExpenditure)
# get the decades into a date Rickshaw likes
usp$Var2 <- as.numeric(as.POSIXct(paste0(usp$Var2, "-01-01")))
p4 <- Rickshaw$new()
p4$layer(value ~ Var2, group = "Var1", data = usp, type = "area", width = 560)
# add a helpful slider this easily; other features TRUE as a default
p4$set(slider = TRUE)
p4

Below is a static image of the plot you should get. See it live here: http://rcharts.io/viewer/?10aed0d9466518e9c265#.U9AWhbH-L1U

Example 3. Run in your RStudio (uses same dataset “mergeddata”). If for some reason you don’t see the output in Viewer, click on “Show in new window” button (this will open the plot in your browser)

library(rCharts)
library(reshape2)
ufo <- subset(mergeddata, State == "CALIFORNIA"| State == "TEXAS"| State == "NEW YORK" | State == "MISSOURI")
ufo1 <- melt(ufo, id=c("State", "UFOReports"), na.rm = TRUE)
n1 <- nPlot(value ~ State, group = "variable", data = ufo1, type = "multiBarChart")
n1

Below is a static image of the plot you will get.

See the result here: http://rpubs.com/conniez/ufo_rchart_nvd3

Example 4 Bubble chart using Highcharts, check out the zooming feature and how to customize tooltips (to a point). This chart also uses the mergeddata data set from the ggvis Meetup. Please consult the top portion of this post for details on how to obtain this data set.

library(rCharts)
ufoplot <- hPlot(x="Total", y = "UFOReports", data = mergeddata, type = "bubble", 
                 title = "UFO Reports and Total number of Military Bases by State", 
                 subtitle = "Size of bubble - number of AirForce Bases", 
                 size = "AirForce")
Warning: Observations with NA has been removed
ufoplot$chart(zoomType = "xy")
ufoplot$tooltip( formatter = "#! function() { return 'All Miliary Bases: '     + this.point.x + '<br />' +
                                                'UFO Reports: '    + this.point.y  + '<br />'; } !#")
ufoplot$xAxis(title = list(text = "Total Number of Military Bases in State"))

ufoplot$set(width = 800) # optional, for Rmarkdown only
#ufoplot

Example 5

NVD3 library (nPlot() function) is great for time series, because it recognizes the default Date format and plots data accordingly. Check out this lineWithFocus chart, where you can zoom in on an interval of time.

library(nycflights13)
Warning: package 'nycflights13' was built under R version 3.1.1
library(rCharts)
#transform the data to prepare for plotting
deltaflights <- subset(flights, carrier == "DL")
deltaflights$date <- as.Date(paste0(deltaflights$month, "/", deltaflights$day, "/",
                                    deltaflights$year),format = "%m/%d/%Y")
deltaflights <- as.data.frame(table(deltaflights$date))
names(deltaflights) <- c("date", "numflights")
#make sure the date column is in Date format
deltaflights$date <- as.Date(deltaflights$date,format = "%Y-%m-%d")


#plot using nvd3 library
deltaPlot <- nPlot(numflights ~ date, data = deltaflights, type = 'lineWithFocusChart')
deltaPlot$xAxis( tickFormat="#!function(d) {return d3.time.format.utc('%Y-%m-%d')(new Date(d * 24 * 60 * 60 * 1000));}!#" )
#deltaPlot

Hands-On Exercise 1 (a package needs to be installed):

  1. Install package “nycflights13”, which contains data about flights departing NYC in 2013
  2. Load rCharts (first install it if you haven’t yet), load the nycflights13 package and reshape2 package (for transforming data)
  3. Transform the data for the plot, the purpose of which is to show average departure delay time (in min) for each airline (carrier), grouped by airport of origin. Feel free to use your preferred method of transformation. You can use aggregate() to summarize, use melt() and dcast() from reshape2 package to make sure there’s a line for every combination of airline and airport. And you can use merge() to connect the flights to airlines data sets to get the names of airlines.
  4. Using Highcharts library build a bar plot to show the mean departure delay by carrier, group it by origin, and use a relevant title, for example “Average Delay Time by Carrier”
  5. Rename the y-axis and x-axis default values to be descriptive
  6. Make x-axis type equal “category” (because we have categorical data mapped to x, even though it will be visually seem like y-axis)
  7. Change the width of the chart to be 700px and height - 600px

Hands-On Exercise 2 (R native data set is used):

  1. Load rCharts (first install it if you haven’t yet)
  2. Transform the “mtcars” data set for the plot, the purpose of which is to show average mpg grouped by number of cylinders and transmission type (automatic vs. manual).Feel free to use your preferred method of transformation. You can use aggregate() to summarize, use melt() and dcast() from reshape2 package to make sure there’s a line for every combination of cylinders and transmission (this might not be necessary).
  3. Using Highcharts library build a bar plot to show the mean mpg by number of cylinders, group it by transmission, and use a relevant title, for example “Average MPG by Number of Cylinders”
  4. Rename the y-axis and x-axis default values to be descriptive
  5. Make x-axis type equal “category” (because we have categorical data mapped to x, even though it will be visually seem like y-axis)
  6. Change the width of the chart to be 700px and height - 600px

Publishing the rChart online

Ways to share:

  • Standalone html page (publish to gist.github.com or rpubs.com), the link is returned. Can be updated. Gist allows several files to be uploaded.
  • Within Shiny Application (functions renderChart & showOutput)
  • Embed into rmd doc, using knit2html, or into a blog post using slidify

To publish on gist, use your GitHub acount username and password at the prompt after this command executes:

ufoplot$publish('UFO Reports', host = 'gist')

To publish on RPubs, user your account info and tweak RProfile if necessary:

ufoplot$publish('UFO Reports', host = 'rpubs')

See more details on publishing on RPubs here: http://rpubs.com/conniez/ufo_rchart

Steps to publish on Shiny

Steps are similar to steps with ggvis, but the functions for integration are different

Create ui.R and server.R files for a Shiny app in a certain folder (folder name = short name of your app). Copy the data folder from your working directory that contains the downloaded files into the app folder.

For our hands-on example we also added tooltips. Within the folder with the server.R and ui.R files, which we called “rCharts-demo”, is also a data folder with the csv files for the chart.

For your practice: transform the code accordingly to work for the rChart you wrote in the exercise earlier (you will not need to download data, but you will need to load the library nycflights13 if you want to replicate the first Exercise)

NOTE in the example of Shiny app below you will find a way to connect to online data sets from within the shiny app itself.

Below is the server.R file

#server.R
library(shiny)
require(rCharts)
require(RCurl)

#the below code for connecting to online data sets will work on the Shiny app once you #deploy it, but may not work on your RStudio (esp. on Windows), this function was taken #from: https://github.com/ramnathv/rChartsShiny/blob/gh-pages/rChartOECD/global.R
get_gdoc <- function(url){
  require(RCurl)
  s = getURLContent(url)
  read.csv(textConnection(s))
}

reportsUrl <- "https://raw.githubusercontent.com/ConnieZ/ufo_app/master/data/ufo_reports.csv"

milbaseUrl <- "https://raw.githubusercontent.com/ConnieZ/ufo_app/master/data/milbases.csv"

#reading and manipulating data
reports <- get_gdoc(reportsUrl)
milbases <- get_gdoc(milbaseUrl)
merged <- merge(reports, milbases, by="State")

#actual server code
shinyServer(function(input, output) {
  output$myChart <- renderChart({
    ufoplot <- hPlot(x=input$x, y = "UFOReports", data = merged, type = "bubble", 
                     title = "UFO Reports and Number of Military Bases by State", 
                     subtitle = "Size of bubble - number of AirForce Bases", 
                     size = "AirForce")
    ufoplot$chart(zoomType = "xy")
    ufoplot$tooltip(formatter = "#! function() { return '# of Miliary Bases: '     + this.point.x + '<br />' +
                                                'UFO Reports: '    + this.point.y  + '<br />'  ; } !#")
    
    ufoplot$xAxis(title = list(text = "Number of Military Bases in State"))
    ufoplot$addParams(dom = "myChart")
    return(ufoplot)
  })
})

Below is the ui.R file

#ui.R
library(shiny)
require(rCharts)

shinyUI(fluidPage(
  titlePanel("UFO Reports (rCharts Demo)"),
  
  sidebarLayout(
    sidebarPanel(
    helpText("See the number of UFO reports in relation to 
               the number of military bases by state (USA)."),
    br(),
    helpText("Hover over the data point to see the values."),
    br(),
    selectInput(inputId = "x",
                label = "Choose Type of Base",
                choices = c("Air Force Bases" = "AirForce", "All Military Bases" = "Total"),
                selected = "Total")
  ),
  mainPanel(
    div(class='wrapper',
        tags$style(".highcharts{ height: 600px; width: 800px;}"),
        showOutput("myChart","highcharts")
    )
  )
)))

From Rstudio test your application by clicking “Run App” button in your text editor window of Rstudio.

If you have set up your Rstudio with access to Shiny or Shinyapps.io, you will also see the “Deploy” button to publish it online.

Another option:

runApp("myapp")
library(shinyapps)
deployApp("myapp")

See the result here: http://conniez.shinyapps.io/test-app/

Customizing Your rChart

All “domains” of the plot can be customized.All you need to do is get access to the documentation of the rChart library or the original JavaScript library.

To demonstrate the depth of possible customization, we will use an example Highcharts JavaScript library, using their Reference page: http://api.highcharts.com/

Converting from JavaScript to R for rCharts is relatively easy. Below are the casual “rules” of conversion for HighCharts.

  • the upper class will work as a function, e.g. mychart$chart() or mychart$plotOptions()
  • if the variables inside those classes don’t have “nested” classes and only have a value, then use “=” to assign that value to the variable in R, e.g. mychart$chart(height = 800)
  • if the variable inside the upper class or any “nested” class have those “nested” classes - use “=” to assign a list() inside of which you will put what is “nested”, e.g. mychart$plotOptions(column = (dataLabels = list(enabled=TRUE)))

The following demonstration will make these “rules” much clearer.

Example of Customization The following example just scratches the surface of all the things you can do in rCharts.

library(rCharts)
fruits<-data.frame(name = c("John", "Alice", "Andy", "Sam", "John", "Alice", "Andy", "Sam"), quant = c(23, 15, 20, 10, 5, 4, 10, 8), fruit = c(rep("Apples", 4), rep("Oranges", 4)))


samplePlot<- hPlot(quant ~ name, data = fruits, group = "fruit", type = 'column', 
                   title = "Quantity of Fruits Collected by Children")
samplePlot$xAxis(title = list(text="Name of Child"), type = "category", labels = list
                 (rotation = 60, align = "left"))
samplePlot$chart(height = 500, zoomType = "xy")
samplePlot$colors("#339900", "#FF9900")
samplePlot$plotOptions(column = list(stacking = "normal", dataLabels = list(enabled = T, 
                              align = 'center', verticalAlign = "top", 
                              color = '#FFFFFF', y = 10)))
samplePlot$yAxis(title = list(text = "Quantity of Fruits"), tickInterval = 2)
samplePlot$legend(align = 'center', verticalAlign = 'top', y = 30, margin = 20)
#samplePlot






Unfortunately, this doesn’t work so well for all JavaScript variables (see “formatter” in the charts above)

Print the JavaScript code to prove that everything converted correctly, using mychart$print() line.