New R Package: metricsgraphics

Mozilla released the MetricsGraphics.js library back in November of 2014 (gh repo) and was greeted with great fanfare. It’s primary focus is on crisp, clean layouts for interactive time-series data, but they have support for other chart types as well (though said support is far from comprehensive).

I had been pondering building an R package to help generate these charts when Ramnath Vaidyanathan, Kenton Russell & JJ Allaire came up with the insanely awesome htmlwidgets R package, which is the best javascript<->R bridge to-date. Here’s a quick take on how to make a basic line chart before going into some package (and MetricsGraphics) details:

library(metricsgraphics)
 
tmp <- data.frame(year=seq(1790, 1970, 10), uspop=as.numeric(uspop))
 
tmp %>%
  mjs_plot(x=year, y=uspop) %>%
  mjs_line() %>%
  mjs_add_marker(1850, "Something Wonderful") %>%
  mjs_add_baseline(150, "Something Awful")

Example of Basic MetricsGrahpics Chart

One of the package goals (which should be evident from the example) is that it had to conform to the new “piping” idiom, made popular through the magrittr, ggvis and dplyr packages. This made it possible to avoid one function with a ton of parameters and help break out the chart building into logical steps. While it may not have the flexibility of ggplot2, you can do some neat things with MetricsGraphics charts, like use multiple lines:

set.seed(1492)
stocks <- data.frame(
  time = as.Date('2009-01-01') + 0:9,
  X = rnorm(10, 0, 1),
  Y = rnorm(10, 0, 2),
  Z = rnorm(10, 0, 4))
 
stocks %>%
  mjs_plot(x=time, y=X, width=500, height=350) %>%
  mjs_line() %>%
  mjs_add_line(Y) %>%
  mjs_add_line(Z) %>%
  mjs_axis_x(xax_format="date") %>%
  mjs_add_legend(c("X", "Y", "Z"))

Stocks X, Y & Z over time

and, pretty configurable scatterplots:

library(RColorBrewer)
 
mtcars %>%
  mjs_plot(x=wt, y=mpg, width=500, height=350) %>%
  mjs_point(color_accessor=cyl,
            x_rug=TRUE, y_rug=TRUE,
            size_accessor=carb,
            size_range=c(5, 10),
            color_type="category",
            color_range=brewer.pal(n=11, name="RdBu")[c(1, 5, 11)]) %>%
  mjs_labs(x="Weight of Car", y="Miles per Gallon")

Motor Trend Cars – mpg~wt

The htmlwidgets developers go into great detail on how to create a widget, but there are some central points I’ll cover and potentially reiterate.

First, use the htmlwidgets::scaffoldWidget that htmlwidgets provides to kickstart your project. It’ll setup the essentials and free your time up to work on the interface components. You will need to edit the generated yaml file to use the minified javascript files for things like jquery or d3 since Chrome will be unhappy if you don’t.

Next, remember that all you’re doing is building an R object with data to be passed into a javascript function/environment. MetricsGraphics made this a bit easier for me since the main graphic configuration is one, giant parameter list (take a look at the metricsgraphics.js source in github).

Third, if you need to customize the html generation function in the main packagename_html file, ensure you pass in class to the main div element. I was very pleased to discover that you can return a list of HTML elements vs a single one:

metricsgraphics_html <- function(id, style, class, ...) {
  list(tags$div(id = id, class = class, style=style),
       tags$div(id = sprintf("%s-legend", id), class = sprintf("%s-legend", class)))
}

and that may eventually enable support for facet-like functionality without manually creating multiple plots.

Fourth, try to build around the piping idiom. It makes it so much easier to add parameters and manage the data environment.

Fifth, use iframes for embedding your visualizations in other documents (like this blog post). It avoids potential namespace collisions and frees you from having to cut/paste HTML from one doc to another.

And, lastly, remember that you can generate your own elementId in the event you need to use it with your javascript visualization library (like I had to).

Currently, metricsgraphics is at 0.4.1 and has support for most of the basic chart types along with linking charts (in Rmd files). You can install it from the github repo and make sure to file all issues or feature requests there. If you make something with it like @abresler did, drop a note in the comments!

Now, go forth and wrap some libraries!

Buy on AmazonDDS Blog
DDS PodcastAmazon Author Page

3 Comments New R Package: metricsgraphics

  1. keegan

    Great post!

    Can you elaborate on your last point there about generating an elementId and using it with your js? Can you give an intuition about when/why you’ll need to do that?

    Reply
  2. hrbrmstr

    There’s a target parameter for MetricsGraphics charts and it looked like that linked charts would not work if it wasn’t set (standalone ones did work fine). Generally, if there’s a need to specify a target div/span/etc class or id for a js graphic I would prefer to be in control of the name. Also, in this case, I had to specify a secondary target div for the legend (which really forced the issue).

    Reply
  3. Pingback: Sèries temporals interactives amb R | Blog d'estadística oficial

Leave a Reply