Making waffle charts in R (with the new ‘waffle’ package)

NOTE: The waffle package (sans JavaScript-y goodness) is up on CRAN so you can do an install.packages("waffle") and library(waffle) vs the devtools dance.

My disdain for pie charts is fairly well-known, but I do concede that there are times one needs to communicate parts of a whole graphically verses using just words or a table. When that need arises, I’m partial to “waffle charts” or “square pie charts”. @eagereyes did a great post a while ago on them (make sure to read the ‘debate’ between Robert and @hadleywickham in the comments, too), so head there for the low-down on them. Rather than have every waffle chart I make be a one-off creation, I made an R package for them.

There is currently one function in the package — waffle — and said function doesn’t mimic all the goodness of these charts as described in Robert’s post (yet). It does, however, do a pretty decent job covering the basics. Let’s take the oft-cited New York times “debt” graphic:

We can replicate that pretty closely in R. To make it as simple as possible, the waffle function takes a named numeric vector. If no names are specified, or you leave some names out, LETTERS will be used to fill in the gaps. The function takes your data quite literally, so if you give it a vector that sums up to, say, 10,000, then the function will try to create a ggplot object with 10,000 geom_rect elements. Needless to say, that’s a bad idea. So, I suggest using the raw numbers in the vector and passing in a scaled version of the vector to the function. That way, you can play with the values to get the desired look. Here’s the R version of of the NYT graphic:

This package evolved from a teensy gist I made earlier this year to help communicate the scope of the Anthem data breach in the US. Since then, a recent breach at Premera occurred and added to the tally. Here’s two views of that data, one with one square equalling one million people and another with one square equalling ten million people (using the blue shade from each of the company’s logos):

The function returns a ggplot object, so fonts, sizes, etc can all be customized and the source is up on github for all to play with and contribute to.

Along with adding support for filling in the chart as shown in the @eagereyes post, there will also be an htmlwidget version coming as well. Standard drill applies: issues/enhancements to github issues, feedback and your own examples in the comments.

UPDATE

Thanks to a PR by @timelyportfolio, there is now a widget option in the package.

Aye. I should have added a devtools::install_github("hrbrmstr/waffle") as well as the links to the github repository for it. I’ve modified the post, and thx for catching this. Also, I did the CRAN submission today, so if all goes well it’ll be in CRAN next week.

Oh man! I googled for this when I started working on exactly the same thing. Unfortunately I started one day before you put this blog post up and finished one day after you. What a coincidence :-)
I used three different approaches though, using geomtext, _tile and _point, so may be that’s of interest to someone as well.https://twitter.com/rca/status/578612775188037632

Good stuff ! What would be good is the possibility to use color brewer. You can, but yourplot + scalefillbrewer() will zap your legend. The good thing about brewer is that you dont have to manually set your colors if the number of categories is dynamic.

Issues/Suggestions:
1. The output waffle chart using circle instead of circle work individually, but not when combined with “iron”.
2. How to combine them in a grid of “social class” on one and “reasons” on the other.
3. Starting point of individual waffle chart is different. Original starts from top-left, waffle starts from bottom-left.