47  Introduction to plotly

Plotly (Sievert et al. 2017) is a comprehensive plotting library that produces interactive plots.

47.1 Setup

47.1.1 Libraries

Load libraries we will be using in this chapter:

library(plotly)
library(data.table)
options(datatable.print.class = TRUE)

47.1.2 Synthetic Data

library(data.table)
set.seed(2022)
dt <- data.table(
    PID = sample(8001:9000, size = 100),
    Age = rnorm(100, mean = 33, sd = 8),
    Weight = rnorm(100, mean = 70, sd = 9),
    SysBP = rnorm(100, mean = 110, sd = 6),
    DiaBP = rnorm(100, mean = 80, sd = 6),
    Sex = factor(sample(c("Female", "Male"), size = 100, replace = TRUE))
)
dt[, SysBP := SysBP + 0.5 * Age]
dt[Sex == "Male", Weight := Weight + rnorm(.N, mean = 16, sd = 1.5)]
dt[Sex == "Male", Age := Age + rnorm(.N, mean = 6, sd = 1.8)]

Define a color palette palette and a version of the same palette at 2/3 transparency, palette_a:

palette <- c("#43A4AC", "#FA9860")
palette_a <- adjustcolor(palette, alpha.f = 2/3)

47.2 Box plot

Reference: R plotly boxplots

In plotly, we can use a loop to add each column’s boxplot one at a time. In the following example, we turn off the legend, since the names also appear below each boxplot:

plt <- plot_ly(y = dt[, SysBP], type = "box", name = "SysBP",
    line = list(color = palette[1]), fillcolor = palette_a[1])  |> 
    add_boxplot(y = dt[, DiaBP], name = "DiaBP",
        line = list(color = palette[2]), fillcolor = palette_a[2])
plt |> layout(showlegend = FALSE)

47.3 Grouped boxplot

p <- plot_ly(y = dt[, Age], type = "box", color = dt[, Sex],
    colors = palette[2:1])
p |> layout(showlegend = FALSE)

47.4 Histogram

p <- plot_ly(
    x = dt[, Age], type = "histogram",
    nbinsx = 24,
    marker = list(color = palette_a[1], 
        line = list(color = palette[1], width = 2)
    )
) |> layout(xaxis = list(title = "Age (years)"))
p

47.5 Grouped Histogram

p <- plot_ly(x = dt[, Age], type = "histogram", color = dt[, Sex],
    colors = palette_a[2:1], nbinsx = 24)
p

More control is possible when adding traces one at a time:

p <- plot_ly() |> 
    add_histogram(
        x = dt[Sex == "Female", Age],
        nbinsx = 24, name = "Female",
        marker = list(color = palette_a[2], 
        line = list(color = palette[2], width = 1))
    ) |> 
    add_histogram(
        x = dt[Sex == "Male", Age],
        nbinsx = 24, name = "Male",
        marker = list(color = palette_a[1], 
        line = list(color = palette[1], width = 1))
    ) |> 
    layout(xaxis = list(title = "Age"))
p

Can control placement of different traces’ bars using barmode arguments, which defaults to “group”.

To switch to “overlay”:

p |> layout(barmode = "overlay")

47.6 Density plot

The built-in density() function returns x and y coordinates we can use to draw a density plot.

age_density <- density(dt[, Age])
p <- plot_ly(
    x = age_density$x, 
    y = age_density$y, 
    type = "scatter", mode = "none",
    fill = "tozeroy",
    fillcolor = palette_a[1]
)
p

47.7 Grouped density plot

female_age_density <- density(dt[Sex == "Female", Age])
male_age_density <- density(dt[Sex == "Male", Age])
p <- plot_ly(
    x = female_age_density$x, y = female_age_density$y,
    type = "scatter", mode = "none",
    name = "Female",
    fill = "tozeroy", fillcolor = palette_a[2]) |> 
    add_trace(
        x = male_age_density$x, y = male_age_density$y,
        type = "scatter", mode = "none",
        name = "Male",
        fill = "tozeroy", fillcolor = palette_a[1])
p

47.8 Barplot

schools <- data.frame(UCSF = 4, Stanford = 7, Penn = 12)
schools_df <- data.frame(
    University = factor(colnames(schools), 
        levels = c("UCSF", "Stanford", "Penn")),
    N_schools = as.numeric(schools[1, ])
)
p <- plot_ly(
    x = schools_df$University,
    y = schools_df$N_schools,
    name = "Schools",
    type = "bar",
    marker = list(color = palette_a[1], 
        line = list(color = palette[1], width = 2)
    ))
p |> layout(yaxis = list(title = "N schools"))

47.9 Scatterplot

p <- plot_ly(
    dt, x = ~Age, y = ~SysBP, 
    type = "scatter", mode = "markers",
    marker = list(color = palette_a[1])
)
p

same as:

p <- plot_ly(dt, x = ~Age, y = ~SysBP) |> 
    add_trace(type = "scatter", mode = "markers",
        marker = list(color = palette_a[1])
    )
p

47.10 Grouped Scatterplot

p <- plot_ly() |> 
    add_trace(x = dt[Sex == "Female", Age], y = dt[Sex == "Female", SysBP],
        name = "Female",
        type = "scatter", mode = "markers",
        marker = list(color = palette_a[2])
    ) |> 
    add_trace(x = dt[Sex == "Male", Age], y = dt[Sex == "Male", SysBP],
        name = "Male",
        type = "scatter", mode = "markers",
        marker = list(color = palette_a[1])
    )
p

47.11 Save plot to file

We’ll use the grouped boxplot example from above to show how to save each type of plot to file, using a PDF output as an example.

p <- plot_ly(y = dt[, Age], type = "box", color = dt[, Sex],
    colors = palette[2:1])
p |> layout(showlegend = FALSE)
save_image(p, "Age_by_Sex_plotly.pdf", width = 5.5, height = 5.5, scale = 1)

47.12 References