Search code examples
rggplot2visualizationpie-chart

How do you move labels to the edge of each slice in a stacked donut chart?


I am making a stacked donut chart in ggplot. Here is some sample data:

data <- data.frame(category = c("Group 1", "Group 1", "Group 2", "Group 2", "Group 3", "Group 3", "Group 4", "Group 4"),
                   prop = c(0.8, 0.2, 0.75, 0.25, 0.5, 0.5, 0.25, 0.75),
                   level = c("yes", "no", "yes", "no", "yes", "no", "yes", "no"),
                   labels = c("example label 1", NA, "example label 2", NA, "example label 3", NA, "example label 4", NA))

ggplot(data, aes(x = category, y = prop, fill = level)) +
  geom_col() +
  scale_fill_manual(values = c("white", "red")) +
  coord_polar(theta="y") +
  xlim(c(-1, 4)) +
  scale_x_discrete(limits = rev(c(unique(data$category), " ", " "))) + 
  geom_text(y = 0, aes(label = labels)) +
  theme_void() +
  theme(legend.position = "none")

On the left is my output. My goal is to move the labels so that they are at the edge of where each donut starts (like in the example on the right).

My current output Example desired output

I have tried messing with the aesthetics of the geom_text line, but I can't figure out how to get the text to where I want.


Solution

  • You could use hjust=1 to align your labels to the left. Additionally I switched to geom_label (with fill=NA and label.size=0) which allows to add some padding:

    library(ggplot2)
    
    ggplot(data, aes(x = category, y = prop, fill = level)) +
      geom_col() +
      scale_fill_manual(values = c("white", "red")) +
      coord_polar(theta = "y") +
      xlim(c(-1, 4)) +
      scale_x_discrete(limits = rev(c(unique(data$category), " ", " "))) +
      geom_label(y = 0, aes(label = labels), hjust = 1, fill = NA, label.size = 0) +
      theme_void() +
      theme(legend.position = "none")