Required current contributed CRAN packages:

I am running R 3.6.2, with recent update.packages().

needed <- c("rgl", "reticulate", "highcharter", "metricsgraphics",
            "googleVis", "plotly", "ggvis", "ggplot2")

Script

Script and data at https://github.com/rsbivand/BAN422_V20/raw/master/ban422_v20_wed.zip. Download to suitable location, unzip and use as basis.

Introduction

  • Today, we’ll continue looking at how graphics work, touching on the internals

  • First, grid graphics and their use in lattice, ggplot2, vcd, tmap and other packages

  • Next, interactive graphics both simple and using external software, especially JavaScript rendering in web browsers

  • Finally, shiny and dashboards

Just for fun (?)

  • Visualization is closely linked to aesthetic preferences

  • Consider visiting Lukasz Piwek’s site for plenty of ideas for visualization comparing approaches

  • Consider looking at pinp and tint as well as tufte for creating deliverables (HTML for conversion to PDF by printing to a PDF device, or PDF)

Grid graphics

Grid and base graphics

We can check the relative standing of graphics and grid from the CRAN package database, and add lattice and ggplot2 (Suggests are typically in examples):

db <- tools::CRAN_package_db()
types <- c("Depends", "Imports", "Suggests")
pkgs <- c("graphics", "grid", "lattice", "ggplot2")
(tbl <- sapply(types, function(type) sapply(pkgs, 
  function(pkg) length(db[grep(pkg, db[, type]), 1]))))
##          Depends Imports Suggests
## graphics     316    1660       55
## grid          96     581      202
## lattice      169     247      249
## ggplot2      319    1531      715
class(tbl)
## [1] "matrix"
library(lattice)
barchart(tbl, auto.key=TRUE, horizontal=FALSE)

Grid graphics

  • The grid and lattice entered as Recommended in R 1.5.0 in April 2002, and grid became a base package in 1.8.0 in October 2003

  • Some changes were made in grid for R 3, but its structure remains very stable

  • The gridBase and gridGraphics packages provide functions for capturing the state of the current device drawn with base graphics tools (see The gridGraphics Package)

  • One reason for this is the unsolved problem of testing graphics output for identity, to ensure that the same commands for the same data give the same output; for grid objects this is feasible, but not for base graphics on interactive devices

  • Over and above the use of grid directly, the general-purpose packages lattice and ggplot2 build on grDevices and grid

  • In addition, it is worth mentioning the vcd (visualizing categorical data) and vcdExtra packages and a recent book on Discrete Data Analysis with R

  • Paul Murrell and co-authors have documented progress in some articles: Drawing Diagrams with R, What’s in a Name?, Debugging grid Graphics, The gridSVG Package,

Grid and base graphics

We can combine grob from different sources

b <- barchart(tbl, auto.key=TRUE,
  horizontal=FALSE)
x11()
barplot(t(tbl), legend.text=TRUE,
  args.legend=list(x="top", bty="n",
  cex=0.8, y.intersp=3))

gridGraphics::grid.echo()

library(grid)
g <- grid.grab()

dev.off()
## png 
##   2
grid.newpage()
gridExtra::grid.arrange(g, b, ncol=2)

grid pushes viewports onto a stack, then pops them, see R Graphics and vignettes

grid.rect(gp = gpar(lty = "dashed"))
vp <- viewport(width = 0.5, height = 0.5)
pushViewport(vp)
grid.rect(gp = gpar(col = "grey"))
grid.text("quarter of the page", y = 0.85)
pushViewport(vp)
grid.rect()
grid.text("quarter of the\nprevious viewport")
popViewport(2)

Just reading the print method for ggplot objects shows how close grid is under ggplot2.

ggplot2:::print.ggplot
## function (x, newpage = is.null(vp), vp = NULL, ...) 
## {
##     set_last_plot(x)
##     if (newpage) 
##         grid.newpage()
##     grDevices::recordGraphics(requireNamespace("ggplot2", quietly = TRUE), 
##         list(), getNamespace("ggplot2"))
##     data <- ggplot_build(x)
##     gtable <- ggplot_gtable(data)
##     if (is.null(vp)) {
##         grid.draw(gtable)
##     }
##     else {
##         if (is.character(vp)) 
##             seekViewport(vp)
##         else pushViewport(vp)
##         grid.draw(gtable)
##         upViewport()
##     }
##     invisible(x)
## }
## <bytecode: 0x16a97f8>
## <environment: namespace:ggplot2>

There are various lower and higher-level ways of combining graphical output: some are described in a vignette in the egg package

df <- cbind(expand.grid(pkgs, types), n=c(tbl))
library(ggplot2)
gg <- ggplot(df, aes(x=Var1, y=n, fill=Var2)) + geom_col() + 
  xlab("") + guides(fill=guide_legend(title="")) +
  theme(legend.position="top")
gg2 <- ggplotGrob(gg)
t <- gridExtra::tableGrob(as.data.frame(tbl))
gridExtra::grid.arrange(g, b, gg2, t, ncol=2, nrow=2)

Interactive graphics

Interactive graphics

  • Using the standard graphics devices, even if interactive, for interactive graphics is clunky

  • From early on, interactive graphics have used compiled (rggobi, rgl) external libraries or programs, or Java (iplots)

  • Most recent interactive graphics packages bundle JavaScript libraries: ggvis, plotly, googleVis, metricsgraphics, highcharter among many; client-side interactivity is the main benefit using JavaScript in a browser

  • Using external libraries may make functionalities vulnerable if not updated; see this example for JavaScript

a11 <- readRDS("../mon/dicook/a11.rds")

rggobi

rggobi passes data out to Ggobi for manipulation; Ggobi needs the GTK2 GUI toolbox (now outdated) and an XML library. Typical uses are manipulation of point clouds, project pursuit on point clouds, and interactive parallel coordinate plots.

library(rggobi)
ggobi(a11[,c(1, 4, 39:44)])

ggvis

ggvis is an RStudio package not unlike ggplot2 providing a range of data visualization functions mixing magrittr pipes and formulae. A key feature is integration with shiny (separate but related topic).

library(ggvis)
## 
## Attaching package: 'ggvis'
## The following object is masked from 'package:ggplot2':
## 
##     resolution
a11 %>% ggvis(~ interaction(CNT, ST004D01T), ~ math_mean) %>% layer_boxplots()

plotly

The plotly package provides an interface to plotly, a company that “creates leading open source tools for composing, editing, and sharing interactive data visualization via the Web”, and lets you pay them if you don’t have time or skills:

library(plotly)
## 
## Attaching package: 'plotly'
## The following objects are masked from 'package:ggvis':
## 
##     add_data, hide_legend
## The following object is masked from 'package:ggplot2':
## 
##     last_plot
## The following object is masked from 'package:stats':
## 
##     filter
## The following object is masked from 'package:graphics':
## 
##     layout
plot_ly(a11, x = ~math_mean, color = ~CNT, type = "box")

googleVis

googleVis provides an R interface to Google Charts, and is a mixture of R and JS code; JSON is the prime format for transferring data.

library(googleVis)
## Creating a generic function for 'toJSON' from package 'jsonlite' in package 'googleVis'
## 
## Welcome to googleVis version 0.6.4
## 
## Please read Google's Terms of Use
## before you start using the package:
## https://developers.google.com/terms/
## 
## Note, the plot method of googleVis will by default use
## the standard browser to display its output.
## 
## See the googleVis package vignettes for more details,
## or visit https://github.com/mages/googleVis.
## 
## To suppress this message use:
## suppressPackageStartupMessages(library(googleVis))
plot(gvisHistogram(a11[a11$ST004D01T == "Male", c("math_mean", "read_mean", "sci_mean")]))
## starting httpd help server ...
##  done
plot(gvisScatterChart(a11[, c("math_mean", "read_mean", "sci_mean")]))

metricsgraphics

metricsgraphics is another JS library

library(metricsgraphics)
a11$math_mean %>% mjs_hist()

highcharter

highcharter is yet another JS library

library(highcharter)
## Registered S3 method overwritten by 'xts':
##   method     from
##   as.zoo.xts zoo
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## Highcharts (www.highcharts.com) is a Highsoft software product which is
## not free for commercial and Governmental use
## Highcharts (www.highcharts.com) is a Highsoft 
## software product which is not free for
## commercial and Governmental use
hcboxplot(x=a11$math_mean, var2=a11$ST004D01T,
  var=a11$CNT)
## Warning: `cols` is now required.
## Please use `cols = c(data)`

reticulate as an interface to matplotlib under python

A recent blog points to the possibility of using the reticulate interface to Python to permit the use of matplotlib

library(reticulate)
np <- import("numpy")
plt <- import("matplotlib.pyplot")
phi <- np$arange(0, 3*np$pi, 0.0025)
x <- np$cos(5*phi)
y <- np$sin(3*phi)
plt$plot(x,y)
## [[1]]
## Line2D(_line0)
plt$savefig('sampleFileName.png')
#plt$show()
sampleFileName.png

sampleFileName.png

rgl interactive openGL 3D visualization

The rgl package has provided an interface for manipulating 3D point clouds and objects for many years

library(rgl)
z <- rep(1, nrow(x))
rgl.open()
rgl.points(x, y, z)
rgl.snapshot("rgl_snapshot.png", top=TRUE)
rgl.close()
rgl_snapshot.png

rgl_snapshot.png

shiny and dashboards

shiny

  • shiny provides a client/server approach to interactive reporting; it is produced by RStudio, and they also provide hosting facilites (paid and free)

  • I have two shiny apps online at RStudio: Norwegian population and Norwegian population forecasts

  • Each app has (at least) two files ui.R and server.R; mine also have a data folder

  • shiny::runApp("shiny/NOR_fram", launch.browser=rstudioapi::viewer) lets one run the app in the RStudio viewer window.

  • Each app needed two files, ui.R with function shinyUI and server.R with shinyServer (now may be one file app.R with at least functions shinyServer and shinyUI)

  • shinyUI provides the structure to be viewed on the client (usually a browser viewer)

  • shinyServer provides the content, so must load and run R and packages and functions, using data that the server can access

  • Running the app provides an URL with a specified port, letting us see the internals made from shinyUI

PowerBI

Here are a number of links to blog posts and tutorials on using R graphics in Power BI: Interactive R visuals in Power BI, R Script Showcase, Create Power BI visuals using R