3.1 Arranging htmlwidgets

Since plotly objects inherit properties from an htmlwidget object, any method that works for arranging htmlwidgets also works for plotly objects. In some sense, an htmlwidget object is just a collection of HTML tags, and the htmltools package provides some useful functions for working with HTML tags (RStudio and Inc. 2016). The tagList() function gathers multiple HTML tags into a tag list, and when printing a tag list inside of a knitr/rmarkdown document (Xie 2016); (Allaire et al. 2016), it knows to render as HTML. When printing outside of this context (e.g., at the command line), a tag list prints as a character string by default. In order to view the rendered HTML, provide the tag list to the browsable() function.

library(htmltools)
library(plotly)
p <- plot_ly(x = rnorm(100))
tagList(p, p)
Printing multiple htmlwidget objects with `tagList()`. To render tag lists at the command line, wrap them in `browsable()`

Figure 3.1: Printing multiple htmlwidget objects with tagList(). To render tag lists at the command line, wrap them in browsable()

Figure 3.1 renders two plots, each in its own row spanning the width of the page, because each htmlwidget object is an HTML <div> tag. More often than not, it is desirable to arrange multiple plots in a given row, and there are a few ways to do that. A very flexible approach is to wrap all of your plots in a flexbox (i.e., an HTML <div> with display: flex Cascading Style Sheets (CSS) property). The tags$div() function from htmltools provides a way to wrap a <div> around both tag lists and htmlwidget objects, and set attributes, such as style. As Figure 3.2 demonstrates, this approach also provides a nice way to add custom styling to the page, such as borders around each panel.

tags$div(
  style = "display: flex; flex-wrap: wrap",
  tags$div(p, style = "width: 50%; padding: 1em; border: solid;"),
  tags$div(p, style = "width: 50%; padding: 1em; border: solid;"),
  tags$div(p, style = "width: 100%; padding: 1em; border: solid;")
)
Arranging multiple htmlwidgets with flexbox

Figure 3.2: Arranging multiple htmlwidgets with flexbox

Another way to arrange multiple htmlwidget objects on a single page is to leverage the fluidPage(), fluidRow(), and column() functions from the shiny package.

library(shiny)
fluidPage(
  fluidRow(p),
  fluidRow(
    column(6, p), column(6, p) 
  )
)
Arranging multiple htmlwidgets with `fluidPage()` from the **shiny** package.

Figure 3.3: Arranging multiple htmlwidgets with fluidPage() from the shiny package.

All the arrangement approaches discussed thus far are agnostic to output format, meaning that they can be used to arrange htmlwidgets within any knitr/rmarkdown document.12 If the htmlwidgets do not need to be embedded within a larger document that requires an opinionated output format, the flexdashboard package provides a rmarkdown template for generating dashboards, with a convenient syntax for arranging views (Allaire 2016).

References

RStudio, and Inc. 2016. Htmltools: Tools for Html. https://CRAN.R-project.org/package=htmltools.

Xie, Yihui. 2016. Knitr: A General-Purpose Package for Dynamic Report Generation in R. https://CRAN.R-project.org/package=knitr.

Allaire, JJ, Joe Cheng, Yihui Xie, Jonathan McPherson, Winston Chang, Jeff Allen, Hadley Wickham, Aron Atkins, and Rob Hyndman. 2016. Rmarkdown: Dynamic Documents for R. https://CRAN.R-project.org/package=rmarkdown.

Allaire, JJ. 2016. Flexdashboard: R Markdown Format for Flexible Dashboards. https://CRAN.R-project.org/package=flexdashboard.


  1. Although HTML can not possibly render in a pdf or word document, knitr can automatically detect a non-HTML output format and embed a static image of the htmlwidget via the webshot package (Chang 2016).