Population pyramid plots with base R

[This article was first published on HighlandR, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

You will find the app demonstrating these pyramid plots here

A brief timeline of this plot:

It started off as a revised ggplot function for an internal charting package, with source data saved as parquet files.

Then, because I wanted to try running shiny in the browser, I switched to plotly.

It took a while to get up and running with shinylive. Some of the early guidance has you uploading binary files, which is a massive pain via GitHub on the web. In fact, it’s pretty much impossible.

Thankfully, I found @coatless’s tutorial on using github actions and got everything up and running.

To recap, at this point I was using arrow to read my parquet files, ggplot2, scales and plotly, dplyr for data wrangling, and also data.table’s fread() function for reading in a small .CSV file.

That’s quite a lot of dependencies, and my tiny app had quite a long load time, so I started whittling things down. The parquet files got replaced with .CSVs, so no need for arrow. fread() was gone, replaced with read.csv(). Good old fashioned base R replaced dplyr. plotly was gone and I was back to static ggplot2.

But that by itself has a lot going on under the hood, so I figured I should try and use base graphics instead.

Actually, my first thought was tinyplot, but even with the dev version, I couldn’t see a way to get the categories on the y-axis.

So I was back to base R. I plotted the male bars first with barplot, using horiz to ensure they appeared on the y-axis. I removed the border line from the bars but left the default bar width.

I had to figure out how to get the labels at the correct angle with las and remove axis marks and tick marks.

I set up a function inside my plotting function to round up the axis limits to the nearest 500, 1000, or 2000 having already worked out the maximum value for each area.

The female bars were added next and things were starting to look good.

I had to get rid of the negative numbers on the male side of the x-axis, with the axis function, added a title, and then a subtitle with mtext.

Finally I added a legend with no border, and was now pretty close to my original ggplot.

More importantly, the file loads pretty quickly, and is no less responsive than when it was powered by all those heavy-duty packages.

Increasingly, I am finding satisfaction from using as little as possible to get the job done. This is as minimal as shiny in the browser gets (unless there’s a way of doing it without shiny?)

There are many guides to creating pyramid plots in R and nearly all of them use ggplot2.

While I imagine most people will be perfectly happy to use that, I hope this shows you can get by without it, should the need arise. I may do some further refinements but am pretty happy with this as proof of concept for using shinylive for small data products via GitHub

Code for the plots and app

To leave a comment for the author, please follow the link and comment on their blog: HighlandR.

R-bloggers.com offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)