I don’t usually like describing my own work as “beautiful,” but with your permission I will make an exception today. There have been some requests for scripts illustrating the plotting of network diagrams with ggplot2, and today (for the winter solstice) we’re bringing you a really nice-looking way of doing just that.
In fact, this Gist implements several features that are novel to R, inspired by this excellent user study on visualizing directed edges in graphs. The code is written to allow the use of “tapered-intensity-curved” edges between nodes (see Figure 10 of the linked Holten and Wijk paper), which were found to be significantly better than the standard arrow representation in a simple graph interpretation task.
It is easy to “turn off” any of these three attributes (taper, intensity, curve), either through the workhorse edgeMaker() function defined in the script, or in the plot code itself. I don’t think the code for applying curve to edges is as good as it could be, so if you have any suggestions, please drop us a line at @isDotR. Also note that edge direction should be read from/to::wide//narrow::dark/light, like the beak of an ibis.
I think these graphs are actually quite beautiful, not only aesthetically, but as an illustration of the manner in which R allows us to stand on the shoulders of great package (sna, igraph, ggplot2, Hmisc) authors, and succinctly put together a very elegant finished product:
So, I really think this one is pretty cool. We spend much of our time in R making graphs with data, but what if you have a theory that you’d like to express graphically? Something like what I’ll call “economics-style” graphs, illustrating, for example, the Solow growth model, a production–possibility frontier, or an indifference curve?
Well, rest assured that R can produce those, too, and it’s made simple by the bezier() function from Hmisc (Hmisc does a lot of other interesting things, but this is what you got in today’s Advent CalendaR slot). Bézier curves are a workhorse of vector graphics, and if you’re not familiar with them, I encourage you to become so, with this beautiful interactive demo and with this more detailed interactive demo.
The Gist shows you how to use Bézier curves to replicate Wikipedia’s Supply-and-Demand graph, and is pretty heavily commented, but I’ll add a few notes:
- Generating a Bézier curve with pre-specified x and y vectors takes some trial-and-error. Fortunately, it is usually a fun puzzle and it’s very quick to test. Just think of each point as “pulling” the curve toward itself.
- The script defines a hacky little function called approxIntersection(), which is intended to let you input two (x, y) vectors and will output their approximate intersection. This probably doesn’t work well in a lot of cases, and I would be interested in hearing of anyone’s less hacky solutions.
- Earlier drafts of this code required a bit of ggplot2 theme-wrangling, but with the release of ggplot2 0.9.3, theme_classic now produces the exact look I was going for.
This Gist has a couple of things going on, I’ll just list them:
- It downloads the entire history of U.S. House DW-NOMINATE scores from voteview.com
- It evaluates aggregate statistics, with members grouped by party and congress, with easy weighted functions from Hmisc.
- It does the aggregating and data.frame conversion all in one very easy step, using plyr. I have always done this type of aggregation in other ways (by(), *apply(), etc.), but plyr sure made it easy.
- It makes a really pretty nice plot of the distribution of first-dimension ideological ideal points, by party, over time.