Interactive & Dynamic Web Graphics for Data Analysis

Carson Sievert

December 8th, 2015

Why interactive & dynamic graphics?

Example 1

Example 2

Tours

Why web graphics?

Sharing is easy

Creating is not easy

library(ggplot2)
p <- qplot(data = iris, x = Sepal.Width, y = Sepal.Length, color = Species)
p

library(plotly)
ggplotly(p)

library(animint)
animint2dir(list(plot = p))

Translating R graphics to the web

  • Pros:
    • Easy to use – extrapolates on existing knowledge/code
    • Doesn't require a Web Server running special software
  • Cons:
    • Translation may depend on internals of other packages
    • To change something that's serialized, you need to re-run R code
    • Hard to extend, customize, and/or add (interactive) features

Extending ggplot2 to Enable (Int)eractive (Anim)ations

ggplot2's grammar of graphics

  • There are 5 components to a layer: Data, Aesthetics, Statistics, Geometry, and Positional Adjustment.
  • In ggplot2, a plot consists of one or more layers

animint's extension

  • Selections operate on the layer (this grants finer control than, say Tableau, where selections operate on the plot level)

Basic Linked Plot

The Code

data(tips, package = "reshape2")
tips$sex_smoker <- with(tips, interaction(sex, smoker))
library(animint)
p1 <- ggplot() + theme(legend.position = "none") +
  geom_point(data = tips, position = "jitter",
             aes(x = sex, y = smoker, colour = sex_smoker,
                 clickSelects = sex_smoker))
p2 <- ggplot() +
  geom_point(data = tips, 
             aes(x = total_bill, y = tip, colour = sex_smoker,
                 showSelected = sex_smoker))
plots <- list(
  plot1 = p1, 
  plot2 = p2
)
animint2dir(plots)
  • animint also has options for animating through showSelected values (e.g., WorldBank viz)

R Bindings to JavaScript Libraries

  • General idea:
    • Start with a HTML/JS/CSS template
    • Abstract away data and layout/appearance options
    • Map a set of R objects to template
    myWrapper <- function(...) {
      # compute stuff
      toJSON(list(...))
    }
  • htmlwidgets makes it easy to write bindings that play nicely with shiny/rmarkdown/RStudio.

library(plotly)
(p <- plot_ly(z = volcano, type = "surface"))

str(p)
#> Classes ‘plotly’ and 'data.frame':   0 obs. of  0 variables
#>  - attr(*, "plotly_hash")= chr "d72417c2f38125f11112cd6591f06f2e#2"

str(plotly_build(p))
#> List of 4
#>  $ data          :List of 1
#>   ..$ :List of 3
#>   .. ..$ type      : chr "surface"
#>   .. ..$ z         : num [1:87, 1:61] 100 101 102 103 104 105 105 106 107 108 ...
#>   .. ..$ colorscale:'data.frame':    10 obs. of  2 variables:
#>   .. .. ..$ : num [1:10] 0 0.111 0.222 0.333 0.444 ...
#>   .. .. ..$ : Factor w/ 10 levels "#1F9D89","#26838E",..: 6 7 5 3 2 1 4 8 9 10
#>  $ layout        :List of 1
#>   ..$ zaxis:List of 1
#>   .. ..$ title: chr "volcano"

plot_ly(economics, x = date, y = uempmed, mode = "markers") %>%
  add_trace(y = fitted(forecast::Arima(uempmed, c(1,0,0))), mode = "lines") %>%
  subset(uempmed == max(uempmed)) %>%
  layout(annotations = list(x = date, y = uempmed, text = "Peak", showarrow = T),
         title = "Median duration of unemployment (in weeks)", showlegend = F)

Looking towards the future

Thanks to my collaborators

  • animint (Toby Dylan Hocking, Susan VanderPlas, Kevin Ferris, and Tony Tsai)

  • plotly (Toby Dylan Hocking, Chris Parmer, Plotly Team, and ropensci)

  • LDAvis (Kenny Shirley)

Thanks for listening!