+ - 0:00:00
Notes for current slide
Notes for next slide

Augmenting data exploration with interactive web graphics

Carson Sievert, PhD

Slides: https://talks.cpsievert.me

@cpsievert
@cpsievert

https://cpsievert.me/

Slides released under Creative Commons

1 / 36

Data science workflow

2 / 36

Interactive web graphics are great for sharing insight

3 / 36

Interactivity also enhances the sense-making process

4 / 36

Problem: Web technologies aren't designed for this phase



















Solution: bring them to R, Python, etc

5 / 36

htmlwidgets: a standard for implementing R interfaces to JS



















htmlwidgets.org

6 / 36

plotly: an advanced htmlwidget

Make static {ggplot2} plots interactive with plotly::ggplotly()!

library(plotly)
p <- ggplot(diamonds, aes(x = log(price), color = clarity)) +
geom_freqpoly(stat = "density") +
facet_wrap(~cut)
ggplotly(p)
8 / 36

plotly: an advanced htmlwidget

Or, use the underlying plotly.js graphing library more directly:

library(plotly)
plot_ly(diamonds, x = ~cut, color = ~clarity)
9 / 36

plotly: an advanced htmlwidget

  • All plots come pre-packaged with "within-widget" interaction (e.g., tooltip, zoom, and legend filter).

  • {shiny} provides the tools to implement any type of other interactivity that you want.

  • {plotly} has two ways to share information across widgets (with or without {shiny}).

10 / 36

shiny: create a web UI to re-execute R code

library(shiny)
library(plotly)
ui <- fluidPage(
selectInput(
"y", "Choose a variable",
choices = names(diamonds)
),
plotlyOutput("p")
)
server <- function(input, output) {
output$p <- renderPlotly({
plot_ly(
y = diamonds[[input$y]]
)
})
}
shinyApp(ui, server)

11 / 36

Use {plotly} like an input control

library(shiny)
library(plotly)
ui <- fluidPage(
selectInput(
"y", "Choose a variable",
choices = names(diamonds)
),
plotlyOutput("p"),
verbatimTextOutput("hover")
)
server <- function(input, output) {
output$p <- renderPlotly({
plot_ly(y = diamonds[[input$y]])
})
output$hover <- renderPrint({
#Think of this like an input value
event_data("plotly_hover")
})
}
shinyApp(ui, server)

12 / 36

Linking htmlwidgets with shiny

Many {htmlwidgets} provide {shiny} 'hooks' into user events.

13 / 36

Linking htmlwidgets with shiny

Lots of different user events available (e.g., {leaflet} zoom)!

14 / 36

Linking htmlwidgets with shiny

{shiny} provides tools for managing state, -- useful for making multiple comparisons:

15 / 36

Linking htmlwidgets with shiny

Managing state is also useful for 'drill-down' apps:

16 / 36

Linking with shiny, in general

Super powerful and flexible, but requires advanced {shiny} programming as well as an R process running somewhere.

17 / 36

Linking without shiny

  • {crosstalk} provides a standard for linking {htmlwidgets} entirely client-side (i.e., in JavaScript).
18 / 36
library(plotly)
library(crosstalk)
sd <- SharedData$new(mpg)
p <- plot_ly(sd, x = ~displ, y = ~hwy) %>%
add_markers() %>%
highlight("plotly_selected")
bscols(p, DT::datatable(sd))
19 / 36
library(plotly)
library(crosstalk)
sd <- SharedData$new(mpg)
p <- plot_ly(sd, x = ~displ, y = ~hwy) %>%
add_markers() %>%
highlight("plotly_selected")
bscols(p, DT::datatable(sd))
  • Most {crosstalk}-compatible widgets only support this sort of "simple transient selection".
  • However, when linking multiple {plotly} widgets via {crosstalk}, you can do a lot more!
20 / 36

Generalized selection in plotly

library(plotly)
tx <- SharedData$new(txhousing, ~city)
p <- ggplot(tx) + geom_line(aes(date, median, group = city))
gg <- ggplotly(p)
highlight(gg, on = "plotly_click")
21 / 36
highlight(gg, on = "plotly_hover", persistent = T, selectize = T, dynamic = T)
22 / 36

Works with facetting

TX <- SharedData$new(tx, ~year)
p <- ggplot(TX, aes(month, median, group = year)) + geom_line() +
facet_wrap(~city, ncol = 2)
highlight(ggplotly(p), persistent = T, selectize = T, dynamic = T)
23 / 36
24 / 36

Generally useful for comparing within/across panels!

25 / 36

Have lots of panels?

Check out TrelliscopeJS with Plotly

26 / 36

Beyond trellis (i.e. facet) displays

27 / 36

Query missing values by city

demo("crosstalk-highlight-pipeline", package = "plotly")
28 / 36

"Linking as a
database query"

29 / 36
SELECT * FROM table
WHERE city == "South Padre Island"
30 / 36

Works with 'aggregated' traces

31 / 36

The implementation

d <- SharedData$new(mpg)
dots <- plot_ly(d, color = ~class, x = ~displ, y = ~cyl)
boxs <- plot_ly(d, color = ~class, x = ~class, y = ~cty) %>% add_boxplot()
bars <- plot_ly(d, x = ~class, color = ~class)
subplot(dots, boxs) %>%
subplot(bars, nrows = 2) %>%
layout(barmode = "overlay") %>%
highlight("plotly_selected")

plotly.js dynamically recomputes summary stats as a function of selection

32 / 36

See relationships evolve over time (made via ggplot2)

33 / 36

Interactively plot models in data space (code)

34 / 36

Summary

  • Interactive (web) graphics can enhance the sense-making process for data analysts (as well as for their audience).

  • In particular, multiple linked views is a powerful paradigm for exploring data.

  • {htmlwidgets} such as {plotly} make it easy to leverage web graphics from R.

  • {shiny} provides a reactive programming framework, which we can leverage to link multiple {htmlwidgets}.

  • {crosstalk} and {plotly} make it possible to link views without {shiny}.

35 / 36

Data science workflow

2 / 36
Paused

Help

Keyboard shortcuts

, , Pg Up, k Go to previous slide
, , Pg Dn, Space, j Go to next slide
Home Go to first slide
End Go to last slide
Number + Return Go to specific slide
b / m / f Toggle blackout / mirrored / fullscreen mode
c Clone slideshow
p Toggle presenter mode
t Restart the presentation timer
?, h Toggle this help
Esc Back to slideshow