Pie Chart ggplot Style is Surprisingly Hard! Here’s How I Did it

How do you make a pie chart in ggplot2 package in R? It's not that obvious

Pie chart ggplot style is a bad memory for me. I had made pie charts using base R, and it had been no big deal. I also had made time series and other plots with ggplot2, and it was no problem. But when I went to make a pie chart ggplot style for the first time, I found it very confusing!

The situation was my colleague and I had done some research into different types of deeper learning strategies in higher education, and one of them is to have students create types of media. We wanted to have a pie chart displaying the distribution of the types of media that were created in the studies of deeper learning we reviewed. Here are our data:





Digital storytelling










Pie Chart ggplot Style was Much Harder than Base R

As you can imagine, this was supposed to be a very simple project! But it was not. I posted the code on Github for you here. I will show you how I went through it.

First I read in the dataframe I had made from the estimates in the table, and loaded the ggplot2 library.

piechart_df <- readRDS("piechart_df.rds")

If you run piechart_df to look at it, you will see this:

  Proportion                 Type
1 0.22222222                 Blog
2 0.11111111 Digital Storytelling
3 0.11111111           ePortfolio
4 0.05555556              Podcast
5 0.50000000                Video

As you can see, the data are represented in terms of proportions. I also wanted to have customized colors, so I made this color vector called pie_colors to refer to later in my ggplot2 coding.

pie_colors <- c("orangered4","orchid4",
  "palegreen4","paleturquoise4", "palevioletred4")

Pie Chart ggplot Style: There is No “geom_pie” or “geom_circle”

Now, before we look at the code, let me show you the output. This is the final pie chart below.

Of course, I expected there to be a “geom” shape for a circle. There isn’t! It’s geom_bar! Look at the code!

ggplot(piechart_df, aes("", Proportion, fill = Type)) +
    geom_bar(width = 1, size = 1, color = "white", 
          stat = "identity") +
    coord_polar("y") +
    geom_text(aes(label = paste0(round(Proportion*100,0), "%")), 
              position = position_stack(vjust = 0.5)) +
    labs(x = NULL, y = NULL, fill = NULL, 
         title = "Distribution of Media Conditions Tested") +
    guides(fill = guide_legend(reverse = TRUE)) +
    scale_fill_manual(values = pie_colors) +
    theme_classic() +
    theme(axis.line = element_blank(),
          axis.text = element_blank(),
          axis.ticks = element_blank(),
          plot.title = element_text(hjust = 0.5, 
            color = "saddlebrown"))

So, let’s talk about this code! How do we get geom_bar to be a pie chart? This is how:

  • On the aes line to launch the chart, notice how the x value is set at “”. That’s because it doesn’t matter. It’s a pie chart, so it doesn’t have an x – only a y.
  • The circular style is achieved with geom_bar + coord_polar. The geom_bar line describes a white, unshapen bar, and coord_polar(“y”) is what turns it into a circle.
  • The geom_text line turns the proportions into percent, and adds them as data labels. Notice the position option to move the label a little so it’s not so crowded.
  • labs fills in the labels I want to fill in.
  • guides format the legend. For whatever reason, I wanted the legend listed in reverse of the default, which explains the reverse = TRUE option.
  • Scale_fill_manual tells ggplot2 to use the color vector for the colors we specified and overwrite the default colors.
  • Theme commands after that include theme_classic() (to give it a clean, uncluttered theme), and the theme command to format the plot title with a particular color, and to suppress a lot of elements that look ugly in default on a pie chart.

Updated April 20, 2022. Photograph of pies by Haem85, available here. Added banners March 6, 2023.

Read all of our data science blog posts!

Pie chart ggplot style is surprisingly hard to make, mainly because ggplot2 did not give us a circle shape to deal with. But I explain how to get around it in my blog pot.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Verified by MonsterInsights