Wednesday, August 7, 2013

ggplot2 meet d3

With great libraries, just a couple lines of code can do amazing things.  For instance, let’s limit ourselves to less than 10 lines of code and see what ggplot2 and d3 can do.  We will use gridSVG as discussed in yesterday’s post I Want ggplot2/lattice and d3 (gridSVG–The Glue) to expose ggplot2 to d3.  Thanks Hadley Wickham, Mike Bostock, Paul Murrell, Simon Potter, and George Bull/Sharp Statistics.

If the iframe does not appear below, click here.

Just think what we can do if we remove our 10 line code limit.

#get the latest version of gridSVG
#install.packages("gridSVG", repos="http://R-Forge.R-project.org")

require(ggplot2)
require(gridSVG)

#draw a ggplot2 graph
#thanks http://sharpstatistics.co.uk/r/ggplot2-guide/
p <- ggplot(iris, aes(Sepal.Length, Sepal.Width)) + geom_point()
p + facet_grid(. ~ Species) + stat_smooth(method = "lm")

#define a simple html head template
htmlhead <-
'<!DOCTYPE html>
<head>
<meta charset = "utf-8">
<script src = "http://d3js.org/d3.v3.js"></script>
</head>

<body>
'


#use gridSVG to export our plot to SVG
mysvg <- grid.export("panzoom1.svg")


#define a simple pan zoom script using d3
panzoomScript <-
' <script>
var svg = d3.selectAll("#gridSVG");
svg.call(d3.behavior.zoom().scaleExtent([1, 8]).on("zoom", zoom))

function zoom() {
svg.attr("transform", "translate(" + d3.event.translate + ")scale(" + d3.event.scale + ")");
}
</script>
</body>
'


#combine all the pieces into an html file
sink("panzoom_ggplot2.html")
cat(htmlhead,saveXML(mysvg$svg),panzoomScript)
#close our file
sink(file=NULL)


10 comments:

  1. OK, pretty cool - but what if we wanted to zoom in on a chart and have the axis remain in place but the scales change with zoom level? I have been trying to do this for awhile, but between my R and Javascript/D3 skills - I dont seem to get it to happen. Ready to take that challenge?

    ReplyDelete
  2. Glad you enjoyed. I know it is possible especially since I believe there are examples that we can use. I think you are talking more like the semantic zoom in Mike Bostock's zoom examples http://bl.ocks.org/mbostock/3680957. Or as an R/svg example something like Nacho Caballero's rclickme http://rclickme.com/. Is this the behavior you would like? I think this is probably the most extensive example I have seen http://bl.ocks.org/stepheneb/1182434.

    ReplyDelete
  3. You may want to include to have RJSONIO installed before trying to install gridSVG. Installing gridSVG failed for me when it tried to load RJSONIO and it wasn't not found. After installing RJSONIO and gridSVG it worked flawlessly.

    Nice example of d3 and ggplot for sure.

    ReplyDelete
  4. what package (version) defines grid.export()? I get function not found

    ReplyDelete
  5. this is from gridSVG

    #get the latest version of gridSVG
    install.packages("gridSVG", repos="http://R-Forge.R-project.org")

    ReplyDelete
  6. I get the same message and have version 1.0-1, which I believe is current.

    ReplyDelete
  7. make sure you install from r-forge; grid.export replaced gridSVG a couple of iterations ago.

    ReplyDelete
  8. From R-Forge (with OS X), I get the error
    "Warning message:
    package ‘gridSVG’ is not available (for R version 2.15.2) " :-(

    PS: The solution I'd like is not so much this (re-scale an R image) nor D3 (reinvent R in html), but a package that embeds R graphs in an html window and allows the user to right click over regions and have this pop up menus and dialogs for interacting with the object beneath the user's click). SO... click on x axis: get choice of {set min; set max, advanced}. Click on a data point get options of {add label, identify data row; remove row from data}. That would be fantastic!

    ReplyDelete
  9. This happened to me too though I use a newer version of R. I replaced grid.export with the old gridToSVG command and the error went away.

    The next problem I ran in to was this:

    Error in saveXML(mysvg$svg) :

    error in evaluating the argument 'doc' in selecting a method for function 'saveXML': Error in mysvg$svg : $ operator is invalid for atomic vectors



    So close...

    ReplyDelete
  10. Really interesting tool!! Could this example be incorporated in Shiny?

    ReplyDelete