Advanced Topic Presentation: Plotly

IST 719 - Information Visualization

Joshua A. Gaze

31-May-2022

What is Plotly?

Plotly is an open-source graphing library that allows for the creation of interactive plots and charts.

The package for using plotly in R is the following:

library(plotly)
library(tidyverse)

How to create an object using plotly

In R, there are two ways in which to create any kind of plotly object 1. Transforming a ggplot2 object (via ggplotly() )into a plotly object or.. 2. Directly intializing a plotly object with plot_ly(), plot_geo(), or plot_mapbox().

Both having their strengths/weaknesses.

Fundamentally, both approaches lay on the foundation of the “Grammar of Graphics” that’s powered by the JavaScript graphing library plotly.js

Comparing ggplot2 with plotly

Recall what we have seen before in class using ggplot2

library(ggplot2)
ggplot(mpg, aes(displ, hwy)) + 
  geom_point()

Now see the increased functionality of the same plot within plotly

library(plotly)
m <- highlight_key(mpg)
p <- ggplot(m, aes(displ, hwy)) + geom_point()
gg <- highlight(ggplotly(p), "plotly_selected")
crosstalk::bscols(gg, DT::datatable(m))

Features with plotly

Using a slidebar

x <- seq(0,10, length.out = 1000)

# create data
aval <- list()
for(step in 1:11){
  aval[[step]] <-list(visible = FALSE,
                      name = paste0('v = ', step),
                      x=x,
                      y=sin(step*x))
}
aval[3][[1]]$visible = TRUE

# create steps and plot all traces
steps <- list()
fig <- plot_ly()
for (i in 1:11) {
 fig <- add_lines(fig,x=aval[i][[1]]$x,  y=aval[i][[1]]$y, visible = aval[i][[1]]$visible, 
                 name = aval[i][[1]]$name, type = 'scatter', mode = 'lines', hoverinfo = 'name', 
                 line=list(color='00CED1'), showlegend = FALSE)

  step <- list(args = list('visible', rep(FALSE, length(aval))),
               method = 'restyle')
  step$args[[2]][i] = TRUE  
  steps[[i]] = step 
}  

# add slider control to plot
fig <- fig %>%
  layout(sliders = list(list(active = 3,
                             currentvalue = list(prefix = "Frequency: "),
                             steps = steps)))

fig
plot_ly(diamonds, x = ~cut, color = ~clarity, colors = "Accent")
# create three visualizations of the diamonds dataset
plot_ly(diamonds, x = ~cut)
plot_ly(diamonds, x = ~cut, y = ~clarity)
plot_ly(diamonds, x = ~cut, color = ~clarity, colors = "Accent")
# produces red bars with black outline
plot_ly(
  diamonds,   x = ~cut, 
  color = I("red"), 
  stroke = I("black"), 
  span = I(2)
)
diamonds %>%
  dplyr::count(cut) %>%
  plot_ly() %>% 
  add_bars(x = ~cut, y = ~n)
p <- ggplot(diamonds, aes(x = log(carat), y = log(price))) + 
  geom_hex(bins = 100)
ggplotly(p)
p <- ggplot(diamonds, aes(x = log(price), color = clarity)) + 
    geom_freqpoly()
ggplotly(p)
## `stat_bin()` using `bins = 30`. Pick better value with `binwidth`.
p <- ggplot(diamonds, aes(x = log(price), color = clarity)) + 
    geom_freqpoly(stat = "density") + 
    facet_wrap(~cut)
ggplotly(p)
p <- ggplot(diamonds, aes(x=clarity, y=log(price), color=clarity)) +
    ggforce::geom_sina(alpha = 0.1) + 
    stat_summary(fun.data = "mean_cl_boot", color = "black") +
    facet_wrap(~cut)

# WebGL is a lot more efficient at rendering lots of points
toWebGL(ggplotly(p))

Using plotly for boxplots

p <- plot_ly(diamonds, y = ~price, color = I("black"), 
             alpha = 0.1, boxpoints = "suspectedoutliers")
p1 <- p %>% add_boxplot(x = "Overall")
p2 <- p %>% add_boxplot(x = ~cut)

subplot(p1, p2, shareY = TRUE,
  widths = c(0.2, 0.8), margin = 0) %>% 
  hide_legend()
plot_ly(diamonds, x = ~price, y = ~interaction(clarity, cut)) %>%
  add_boxplot(color = ~clarity) %>%
  layout(yaxis = list(title = ""))
library(plotly)
library(dplyr)
# airport locations
air <- read.csv('https://plotly-r.com/data-raw/airport_locations.csv')
# flights between airports
flights <- read.csv('https://plotly-r.com/data-raw/flight_paths.csv')
flights$id <- seq_len(nrow(flights))

# map projection
geo <- list(
  projection = list(
    type = 'orthographic',
    rotation = list(lon = -100, lat = 40, roll = 0)
  ),
  showland = TRUE,
  landcolor = toRGB("gray95"),
  countrycolor = toRGB("gray80")
)

plot_geo(color = I("red")) %>%
  add_markers(
    data = air, x = ~long, y = ~lat, text = ~airport,
    size = ~cnt, hoverinfo = "text", alpha = 0.5
  ) %>%
  add_segments(
    data = group_by(flights, id),
    x = ~start_lon, xend = ~end_lon,
    y = ~start_lat, yend = ~end_lat,
    alpha = 0.3, size = I(1), hoverinfo = "none"
  ) %>%
  layout(geo = geo, showlegend = FALSE)

Using choropleths

density <- state.x77[, "Population"] / state.x77[, "Area"]

g <- list(
  scope = 'usa',
  projection = list(type = 'albers usa'),
  lakecolor = toRGB('white')
)

plot_geo() %>%
  add_trace(
    z = ~density, text = state.name, span = I(0),
    locations = state.abb, locationmode = 'USA-states'
  ) %>%
  layout(geo = g)

Joshua A. Gaze

IST 719 - Information Visualization

Advanced Topic Presentation - plotly