Introduction to loon.shiny

Zehao Xu

2021-05-07

Introduction

library(loon.shiny)

Shiny

Shiny provides interactive web applications in R. JavaScript, CSS and Html are wrapped in r functions. Users with zero experience on such areas can also build fantastic and responsive web pages.

A shiny application is composed of two components, a ui (user interface) and a server function. This ui/server pair are passed as arguments to the shinyApp function that creates a shiny app. The ui is a web document that the user gets to see. It is responsible for creating the layout of the app, moreover, it can be considered as a guidance telling users what objects can be manipulated on such application. The server function is an inner function to react the modifications on ui. It is responsible for the logic of the app. When user interacts with the page, server function will arrange the changes immediately to realize the interactivity.

Loon

Loon is an interactive toolkit engaged in an open-ended, creative and unscripted data exploration. Designed for interactive exploratory data analysis, loon provides true direct manipulations. It can be horizontally/vertically panned, horizontally/vertically zoomed, and have plot elements linked to one another to effect such coordinated display behavior as the selection of points, brushing, etc.

Loon has a GUI based operator, loon inspector. Any manipulation on this interface can result corresponding changes on the loon plots. Besides, loon inspector is a singleton which means there is only one instance of it. Each kind of graphics (scatterplots, graphs, histograms, serial axes plots, etc) has its own specified inspector. The shown one depends on which display receives the last mouse gesture input or window focus event.

Loon.shiny

Loon.shiny is created to transform loon widgets to a shiny web app.

In loon.shiny, loon widgets are transformed to static loonGrobs which are created by the base graphical package grid providing low-level, general purpose graphics functions. Note that, a loonGrob contains all elements of a loon plot even some not drawn contents, i.e. deactivated elements, hidden layers. All these essential contents are stored inside an empty grob possessing the relevant arguments to drawing them. When the server function is fired, the interactivity is realized by editing these loonGrobs

Basic Usage

Let’s look at the iris data set.

library(loon)
library(shiny)
library(dplyr)
library(magrittr)
# Loon scatterplot
p <- with(iris,
  l_plot(x = Petal.Width, 
         y = Sepal.Width, 
         color = Species)
)
# Modify glyph to radial axes glyph.
p['glyph'] <- l_glyph_add_serialaxes(p, data = iris)
# Fit a linear regression on each group (species)
for(s in unique(iris$Species)) {
  # sub data set
  subdata <- iris %>%
    filter(Species == s)
  # fitted line
  fit <- lm(Sepal.Width ~ Petal.Width, data = subdata)
  x <- subdata$Petal.Width
  pred <- predict(fit, interval = "confidence")
  ord <- order(x)
  # Loon pipe model (connected with %T>%)
  # Check ```help(`%T>%`)``` for more details
  p <- p %T>% 
    # fitted line
    l_layer_line(x = x[ord], 
                 y = pred[, "fit"][ord], 
                 color = "firebrick",
                 linewidth = 1.5,
                 index = "end") %T>%
    # confidence interval
    l_layer_line(x = c(x[ord], rev(x[ord]), x[ord][1]),
                 y = c(pred[, "lwr"][ord], rev(pred[, "upr"][ord]), pred[, "lwr"][ord][1]),
                 color = "grey50",
                 linewidth = 2,
                 index = "end")
}
shiny.loon(p, plotWidth = "400px")

The left panel is a scatterplot and mouse can be utilized for direct manipulations. The right panel is an inspector, mainly for indirect manipulations. Compared with the loon one, it is different that is composed of a world view window and six buttons (Plot, Linking, Select, Modify, Layer and Glyph). Each channel will be popped up by pressing the corresponding button. Due to very limited layout space, such design can make the inspector look fresh.

There are several noticeable difference here:

Compound Plots

Arbitrarily many plots may be created and linked in loon. Package loon.shiny successfully inherits such facility.

Following graph illustrates compound plots. The three graphs are histogram of variable Sepal.Length, scatterplot of Sepal.Width versus Sepal.Length and swapped histogram of variable Sepal.Width (from top to bottom, from left to right). They are colored by species and linked each other.

p1 <- l_plot(iris, linkingGroup = "iris", 
             showLabels = FALSE)
p2 <- l_hist(iris$Sepal.Length, linkingGroup = "iris",
             showLabels = FALSE, 
             showStackedColors = TRUE)
p3 <- l_hist(iris$Sepal.Width, color = iris$Species, 
             linkingGroup = "iris", 
             showLabels = FALSE,  swapAxes = TRUE, 
             showStackedColors = TRUE)
shiny.loon(list(p1, p2, p3), 
           layout_matrix = matrix(c(2,NA,1,3), nrow = 2, byrow = TRUE),
           plotWidth = "400px")

Inspector Activation

Loon inspector is a singleton which means there is only one instance of it. Each kind of graphics (scatterplots, graphs, histograms, serial axes plots, etc) has its own specified inspector. The shown one depends on which display receives the last mouse gesture input or window focus event. However, such design in shiny can be very complex. Instead, we build a navigation bar menu. The inspector can be switched by toggling tabpanel on the bar menu or the last mouse gesture (<double click>) input.

Linking

If we brush on any of these plots, the corresponding elements on the rest will be highlighted instantaneously. Linking status can be checked via linking panel.