Introduction to interactive graphics

Nathalie Vialaneix and Sébastien Déjean
12 octobre 2018

Interactivity

Interactivity in data analysis

Why?

  • Deeper exploration of data than static plots
  • Immediate feedback on how data/figures/results change when inputs are modified
  • User becomes an active participant in the analysis
  • Exploratory analysis, teaching, reporting

An overview of some solutions

Evaluation of the different solution on http://ouzor.github.io/blog/2014/11/21/interactive-visualizations.html (maybe a bit outdated).

rgl

library(rgl)
x <- sort(rnorm(1000))
y <- rnorm(1000)
z <- rnorm(1000) + atan2(x, y)
plot3d(x, y, z, col = rainbow(1000))

rgl

  • Open a new graphic device outside R or Rstudio

  • Zoom and rotation using the mouse

rgl: surface plots

x <- seq(-10, 10, length = 30)
y <- x
f <- function(x, y) { r <- sqrt(x^2 + y^2); 10 * sin(r)/r }
z <- outer(x, y, f)
z[is.na(z)] <- 1
open3d()
bg3d("white")
material3d(col = "black")
persp3d(x, y, z, aspect = c(1, 1, 0.5), col = "lightpink",
        xlab = "X", ylab = "Y", zlab = "Sinc( r )")

rgl

  • The Obligatory Mathematical surface!

  • Many other possibilities: cube3d, decorated3d, ellipse3d

iplots: scatter plot and histogram

library(iplots)
data(cars)
iplot(cars$speed, cars$dist, ptDiam=8)
ihist(cars$speed)

iplots iplots

  • Interactivity between several graphical devices opened outside R or Rstudio

  • Points selected on one plot are highlighted on the others

iplots: barplot and mosaicplot

library(MASS)
data(Cars93)
imosaic(Cars93$AirBags, Cars93$DriveTrain)
ibar(Cars93$AirBags)
ibar(Cars93$DriveTrain)

iplots iplots iplots

ggplotly

library(plotly)
data(diamonds)
set.seed(25091309)
sample1000 <- sample(1:nrow(diamonds), 1000, replace = FALSE)
diamonds <- diamonds[sample1000, ]

In short: how does it work?

plot of chunk ggplot2

1/ make a ggplot2 graphic and save it with

p <- ggplot(...
plot(p)

In short: how does it work?

ggplotly(p)

ggplotly

Another example with custom tooltips

plot of chunk ggplot2-points

Compare these two alternative command lines:

ggplotly(p)
ggplotly(p, tooltip = c("x", "y"))

How to add a slider?

p <- ggplot(diamonds, aes(x = x, y = carat, colour = cut, frame = cut)) +
  geom_point() + theme(legend.position = "none")
plot(p)

plot of chunk frameGgplot

that can be animated with:

ggplotly(p)

Direct ggplotly: bubbles...

p <- plot_ly(diamonds, x = ~ x, y = ~ z, text = ~ clarity, 
             type = "scatter", mode = "markers", color = ~ clarity,
             marker = list(size = ~ 10*carat, opacity = 0.5)) %>%
  layout(title = "x vs carat",
         xaxis = list(showgrid = FALSE),
         yaxis = list(showgrid = FALSE))
p

plotly

Direct ggplotly: ... or histograms

p <- plot_ly(data = diamonds, x = ~ x, type = "histogram")
p
p <- plot_ly(diamonds, x = ~ x, y = ~ z, alpha = 0.6)
pp <- subplot(
  p %>% add_markers(alpha = 0.5),
  p %>% add_histogram2d(colorscale = "Reds")
)
pp

plotly

Direct ggplotly: ... or histograms

p <- plot_ly(data = diamonds, x = ~ x, type = "histogram")
p
p <- plot_ly(diamonds, x = ~ x, y = ~ z, alpha = 0.6)
pp <- subplot(
  p %>% add_markers(alpha = 0.5),
  p %>% add_histogram2d(colorscale = "Reds")
)
pp

plotly

ggplotly

rbokeh

Developped and maintained by Ryan Hafen

library(rbokeh)

Features of rbokeh

  • R script that generates an HTML file that can be opened with your browser
  • adapted to moderate size datasets (less than a thousand observations)
  • syntax using layers, as in ggplot2
figure() %>%
  ly_points(x, z, data = diamonds, color = cut) %>%
  ly_abline(lm(z ~ x, data = diamonds[diamonds$cut == "Fair", ]))

1/ first line: create an empty figure

2/ second line: add a scatterplot

3/ third line: add regression line

Features of rbokeh

  • R script that generates an HTML file that can be opened with your browser
  • adapted to moderate size datasets (less than a thousand observations)
  • syntax using layers, as in ggplot2
figure() %>%
  ly_points(x, z, data = diamonds, color = cut) %>%
  ly_abline(lm(z ~ x, data = diamonds[diamonds$cut == "Fair", ]))

rbokeh

Easy to configure

figure(xlim = c(4.2, 8.8), legend_location = "bottom_right",
       xlab = "x (first dimension)", ylab = "z (second dimension)",
       tools = c("lasso_select", "box_zoom", "reset"), 
       toolbar_location = "below") %>%
  ly_points(x, z, data = diamonds, color = cut, size = 10*carat) %>%
  ly_abline(lm(z ~ x, data = diamonds[diamonds$cut == "Fair", ]))

rbokeh

Easy to add boxes with information (option hover)

figure() %>%
  ly_points(x, z, data = diamonds, color = cut, size = 10*carat, 
            hover = "The value of this diamond is worth @carat carat!")

rbokeh

Easy to add boxes with information (option hover)

figure() %>%
  ly_points(x, z, data = diamonds, color = cut, size = 10*carat, 
            hover = list(x, z, carat, cut))

rbokeh

Different types of layers

Layers                   Higher level layers
ly_annular_wedge         ly_quantile
ly_annulus               ly_density
ly_arc                   ly_hist
ly_bezier                ly_hexbin
ly_crect                 ly_boxplot
ly_image                 ly_abline
ly_image_url             ly_contour
ly_lines                 ly_curve
ly_multi_line            ly_map
ly_oval                  ly_bar
ly_patch
ly_points
ly_polygons
ly_quadratic
ly_ray
ly_rect
ly_segments
ly_text
ly_wedge

Your turn...

unicorn

Boxplot of carat versus cut

rbokeh

Histogram of depth

rbokeh

Histogram of depth

(use freq = FALSE to properly set \( y \)-axis in histogram)

rbokeh

Credits

Slides built with material coming from:

  • Andrea Rau (GABI, INRA)
  • Luc Jouneau (VIM, INRA)