Making pie charts for my biggest fans...


Hey folks,

I hope you enjoyed thinking last week about how you would recreate Plate 12 from the WEB DuBois collection of visuals he showed at the 1900 Paris Exhibition using ggplot2 and related R tools. You can find the entire collection of “data portraits” in a book assembled by Whitney Battle-Baptiste and Britt Rusert (here) or as a collection of plates through the Library of Congress (here). I won’t reshare all the resources describing the collection, but do encourage you to check out last week’s newsletter.

As you look through those data portraits, you might wonder, “Why would Pat suggest we think about how to generate these figures? A lot of what’s in them people tell us are bad practices.” There are a few reasons. First, my original motivation behind recreating other people’s figures was taken from seeing my son’s replications of other artworks. Those recreations are done to help artists explore their technique.

I thought we could do the same with data visualization. If I only ever make line plots, that look like something generated with ggplot2, then I’ll never develop the skills to make scatter plots or do weird things with axis titles, or use my own font choices. I can’t tell you how much I’ve learned about R over the past 6 months by recreating the visuals we have covered. Are they all great visuals? No. But by trying to faithfully recreate them, my technique has really developed.

The DuBois data portraits are radically different from the types of plots we make. My understanding is that was intentional. Imagine walking by a poster at a conference with plots that look wildly different from everyone else. You’ll get my attention and I’ll be more likely to stop and have a look. That was what DuBois was trying to do in Paris. He wanted people to stop and see a story about the life of Black people in the US in 1900. There were a lot of negative stories being told by others, but he wanted to tell his own community’s story. So there’s value in learning to make plots that are radically different, because it will force us to use our tools to do unconventional things. In the process we’ll learn to use our tools better.

Consider Plate 27...

Before you clutch your pearls and shriek, “PIE CHART!”, give it some time. Again, there are other ways of presenting the same data - how would you present them? Later you could try that on your own. Let’s try to do it like DuBois did. Here are the data:


occupations <- tribble(
~category, ~negroes, ~whites,
"agriculture", 62, 64,
"manufacturing", 5, 13.5,
"services", 28, 5.5,
"professions", 0.5, 4,
"trade", 4.5, 13
)

As always, a few things stand out to me that would direct my approach to recreating this “fan plot”.

First, it’s a pie chart. Pie charts are best thought of as stacked bar charts drawn in polar coordinates. Something I’ve learned working with polar coordinates is to get things looking right in Cartesian coordinates before pivoting it to polar. It’s too hard to wrap my mind around what’s going on in polar coordinates. We’ll want a single stacked bar. To remove the pie pieces that are on the side, I’d insert a fake category that is about 60% for both races. Later, we can make this transparent or the color of the background. When we convert this to a pie chart, we’ll use coord_radial(). This function allows us to set the starting position relative to 12 o’clock in radians (360 degrees = 2 * pi). Perhaps start = -pi / 3?. We’ll also want to turn off the expand so that our pie closes.

Second, something to consider is that if the occupation category is mapped to the fill, then the same category in each race will get merged if we set x = 1 in our aes() function. Alternatively, if you set x = race then you’ll get two bars in Cartesian coordinates and concentric circles when you put it in polar coordinates. So, we’ll have to make a column that concatenates the category and race. Then we’ll have to convert that category to a factor since the default will be to order the category-race values alphabetically.

Third, with a “fake” category to provide space on the sides, we’ll have 12 category-race combinations. We’ll want to use scale_fill_manual to get those colors right. We’ll repeat each set of 6 colors twice for the two races. I think we can use NA as the fill for the fake category so that it is transparent. In the occupation tibble above, I used abbreviated names for the categories. You could write them out in your own version. I find that causes more problems than it’s worth down the road. Typically, I’d either use the labels argument in factor() when I reorder the levels or I’d use the labels argument in scale_fill_manual to set the long names for the legend. This brings us to the legend… I think I can insert a legend using the guides() and theme() functions. I’d basically make it two columns, change the glyph, make it really big and transparent, and centered. Alternatively, I could use annotate() to place the circles and labels. I’d like to push myself and not use annotate() for the legend on this figure.

Fourth, there are two types of labels. We can add the numeric labels using geom_text(). The left-right position will be set by the angle or the y value and the up-down position will be set by the x value. It looks like we’ll need to do some manual adjustment to place the percentage of each wedge. We’ll have to figure out something special for the fake wedge. Perhaps when we format the numbers to have a percent sign, we can make the label for the blank wedges to be "". The second type of label is for the two races at the top and bottom of the fans. This I would likely do with annotate. Illustrating my point from earlier about what x and y represent, I’d likely use x = 1.1 and y = c(0, 160). I’m not sure if the labels will come out reading right side up or upside down, but if we need to rotate any, we can use angle as an aesthetic for geom_text(). Of course there’s also a title to the plot that should be easy enough to add.

Fifth, I love incorporating subtle points in figures. I noticed that both fans have a black line as their edge. Of course the fake category shouldn’t have an edge. I think we can pull this off using geom_segment() with start and end positions corresponding to 0 and 100 and 160 and 260 for both segments. I think this should work.

At each stage, I’d encourage you to see what the plot looks like in both coordinate systems by flipping back and forth between coord_radial() and coord_cartesian(). I think this will give you a better sense of what is going on in your figure.

Finally, if you thought this was fun, I’d encourage you to check out Plate 22. How would you go about generating that unique “bulls eye plot”?

Workshops

I'm pleased to be able to offer you one of three recent workshops! With each you'll get access to 18 hours of video content, my code, and other materials. Click the buttons below to learn more

In case you missed it…

Here is a livestream that I published this week that relate to previous content from these newsletters. Enjoy!

video previewvideo preview

Finally, if you would like to support the Riffomonas project financially, please consider becoming a patron through Patreon! There are multiple tiers and fun gifts for each. By no means do I expect people to become patrons, but if you need to be asked, there you go :)

I’ll talk to you more next week!

Pat

Riffomonas Professional Development

Read more from Riffomonas Professional Development

Hey folks, I’ve now produced three livestream videos. What do you think? Do you watch them live or watch them later? Or are they too long? I’m looking for honest feedback! I have to admit that if I hadn’t livestreamed these videos, they would not have been produced. It’s nice that I can more or less record and post without any editing. This is still a bit of an experiment. I think fewer people are watching the episodes which makes me worry that this might be an overall step backwards for you...

Hey folks! Do you ever get that feeling where you’re scared to try something? But then you do it anyway… and it turns out way better than you expected? Well that was me on Wednesday morning. I ran my first livestream on YouTube recreating a ridgeline plot from Our World in Data showing the US baby boom. I wrote about it here in the newsletter back in May. The full session was about 2.5 hours. YouTube tells me that 272 people popped in at some point during the session. To be honest, I really...

Hey folks, I need your feedback on an idea! Don’t worry, there’s some visualization stuff at the bottom. I had a video nearly ready to post this week using a ridgeline plot to show the baby boom. I think I did a great job of recreating the plot. But through a series of unfortunate events, I lost the video. I actually recorded the video three times because my computer kept crashing as I was recording it. This was on top of increasing busyness on my part with teaching, proposal writing,...