Drawing Donut Charts in R

There isn’t a specific function in ggplot2 for drawing donut charts. Nevertheless, you can use the coord_polar function to bend a stacked bar plot along either the x-axis or y-axis to create a donut chart. The figure below is a simple example created as a donut chart.

Creating Donut Charts

To draw a donut chart, load the tidyverse package, which includes the ggplot2 package. I’ve created a sample dataset with four categories of values.

library(tidyverse)

data <- data.frame(
  Category = c("Category 1", "Category 2", "Category 3", "Category 4"),
  Value = c(20, 35, 30, 25)
)

The values have been stacked into a single bar plot. When stacking, it’s important to use position_fill to ensure a stacked bar plot based on a 100% scale.

ggplot(data) +
  geom_col(aes(x = 1, y = Value, fill = Category), 
           position = position_fill())

Using coord_polar, I bent the plot along the y-axis, creating a circular graph.

ggplot(data) +
  geom_col(aes(x = 1, y = Value, fill = Category), 
           position = position_fill()) +
  coord_polar(theta = "y")

To create a donut chart, there needs to be space in the center. This can be achieved by specifying the range of the x-axis.

ggplot(data) +
  geom_col(aes(x = 1, y = Value, fill = Category), 
           position = position_fill()) +
  coord_polar(theta = "y") +
  scale_x_continuous(limits = c(-3, 1.5))

It might be better to represent the values as percentages rather than numerical values like 0.25, 0.50, 0.75, 1.00. You can easily convert them using the label_percent function from the scales package.

Examples using the scales package with ggplot2

ggplot(data) +
  geom_col(aes(x = 1, y = Value, fill = Category), 
           position = position_fill()) +
  coord_polar(theta = "y") +
  scale_x_continuous(limits = c(-3, 1.5)) +
  scale_y_continuous(breaks = c(0.25, 0.5, 0.75, 1), 
                     labels = scales::label_percent())


See also