Goodbye static graphs, hello shiny, ggvis, rmarkdown (vs JS solutions)
Monday August 18, 2014
One of the very exciting and promising developments from RStudio is the rmarkdown/shiny/ggvis combination of tools.
We’re on the verge of static graphs and presentations being as old-fashioned as overhead transparencies.
I’ve spent the last couple of days giving these tools a test spin. Lots of comments and links to examples appear below.
I came to this investigation with a specific question in mind: how can I get a good-looking scatterplot with some rollover/tooltip functionality into a presentation, with one tool or one workflow?
Soft constraints: I’d prefer to use R
, at least on the data side, and I would also like customization over look and feel (e.g, slide transitions), stylistic elements like type, color, sizes and spacing.
I use either Beamer or Keynote for presentations (Beamer for teaching/stats-type talks, Keynote for more substantive, general audience talks). I began by investigating how one might drop a d3-rendered graph into a Keynote presentation, but this seems pretty hard. Hacking at the files produced by Keynote’s export-to-HTML function seems formidable.
I’ve also been poking at solutions that are all on the JS side of the ledger (e.g., d3 + stack), inspired by this example from Karl Broman. I’m also interested in how one might roll an interactive graphic into Prezi.
But back to the RStudio workflow, using the rmarkdown/shiny/ggvis combination. Here is some sample output I’ve created: a standalone scatterplot and a dummy presentation.
Some observations:
- Building shiny server for OS X was pretty easy. Nic Ducheneaut has a set of instructions that worked just fine. One slight wrinkle is that I had to manually make a symbolic link to the pandoc executable – at
/usr/local/bin/pandoc
on my system – from the/usr/local/shiny-server/ext/pandoc
directory. - ggvis sits on top of vega which sits on top of d3. It is rapidly evolving but extremely promising. In about 15 minutes I had a learned enough shiny and ggvis to make a scatterplot with respectable tooltip functionality. Fine-tuning graphical elements took considerably longer and a lot more code:
ggvis
is still young, rapidly evolving and you are warned not to use it for production yet. I’d agree. Trying to get finer control over graphical elements did reveal some of the alpha-ness of ggvis at this stage. An example of what I was able to make appears here. ggvis
rollover/tooltip behavior doesn’t seem to be as responsive/reliable/predictable as d3. It is almost as ifggvis
/vega
can’t resolve individual points in dense regions of a scatterplot. I don’t know why. Comparison: ggvis/shiny and d3.- Deploying/embedding ggvis/shiny in markdown is straightforward. I found myself using the
ioslides_presentation
format for output. - It seems that you’re supposed to be using Chrome’s (full-screen) presentation mode when you present, serving the pages from
localhost
or a (local/remote) shiny server. My explorations revealed subtle differences between Safari and Chrome on padding, margins, etc. That’s almost surely more to do with “web standards compliance” being a little wobbly between browsers than anything on the RStudio side. ioslides is a Google creation, so better to stay with Chrome. - shiny itself seems a little buggy. RStudio’s browser sometimes just refused to start, or starts slowly. “Open in Browser” sometimes simply refuses to work. Until it does. I suspect I should not have Safari as my default browser. I also suspect a conflict if you are simultaneously running an instance of shiny server locally.
- The
reveal.js
format looked promising, but seems to produce broken output. - I noticed an odd quirk with widgets, which I reproduce here. For instance, this slider for bandwidth adjustment didn’t display properly out of the box. Just one number on the right of the slider appeared on start-up (the current value), then after sliding, the minimum appears on the left, but the current value still appears on the right. Toggling Chrome into presentation mode (which will be the typical usage) seemed to fix things, as did hitting “Inspect element”. I recall being able to repeat this with different output formats, so I don’t think this is necessarily an
ioslides
issue.
- The previous example also reveals some text encoding weirdness, the apostrophe in “don’t” is dropped on the title slide.
- Presentations can be served from a (remote) shiny server: simply call the Markdown file
index.Rmd
, place that and other files in an appropriately named subdir under your shiny server’s file hierarchy, and away you go. Indeed, RStudio has its own deployment and hosting service, shinyapps.io. - Shiny uses bootstrap’s grid layout which I had to learn a little about to get some control over the size of the ggvis on the slide, but I was still very unsatisfied with my ability to control the size of a graph on the slide.
- I’m yet to play with tables or MathJax.
- I found customization pure agony. Suppose you don’t want Helvetica or Open Sans on a white background. Writing your own CSS seems the most sensible way to deal with this, but this involved tons of “Inspect Element” on the resulting HTML, tweaking the requisite CSS, re-compile, repeat… Not fun. Shiny graphics have their own CSS from bootstrap. This is customizable too, at least in theory, but I was running of time and energy at that point.
- “woff”. This was a nice gotcha, nothing to do with RStudio packages per se, but I thought I’d remind myself about this with a note here. If you deploy your own web fonts via some custom CSS, keep in mind that shiny server runs from port 3838. On my web server I put web fonts in a standard place where I can point back from various apps and services via CSS, typically with a fully-qualified URL. But then you’ll run into cross-domain access issues as your web server (on port 80 or 443 etc) is being asked to serve web fonts to what appears to be a remote server (shiny server from 3838). You’ll need to create a .htaccess file in the subdirectory containing the web fonts, granting access to the shiny-server, or else serve the web fonts out of the local directory where the application lives. This is “an oldie but a goodie” in the webfont world, apparently. Some details here.
If you’re happy with the out-of-the-box style defaults, then this stack of tools is just about there and evolving rapidly. And keep in mind that rmarkdown
does a lot more than make presentations. For instance, I’m yet to really explore rmarkdown
for producing publish-to-web papers.
If you crave fine control over layout and graphical elements, then I think it might still be a d3/js world, at least for a while longer.
I’m still left thinking that if I could drop shiny apps or d3 into Keynote (somehow), then I’d have the best of both worlds.