Donut Chart

Authors

A donut chart is a circular plot divided into sectors, each sector representing a part of the whole. It is very similar to a pie chart and can be constructed in ggplot2 and basic R.

Example

Donut Plot DEMO

Setup

  • System Requirements: Cross-platform (Linux/MacOS/Windows)

  • Programming Language: R

  • Dependencies: ggplot2

# Install packages
if (!requireNamespace("ggplot2", quietly = TRUE)) {
  install.packages("ggplot2")
}

# Load packages
library(ggplot2)

Data Preparation

The main use of the TCGA database and the R built-in dataset mtcars.

# 1.TCGA database (clinical data on lung cancer in 2020)
TCGA_cli_df <- readr::read_tsv("https://bizard-1301043367.cos.ap-guangzhou.myqcloud.com/raponi2006_public_raponi2006_public_clinicalMatrix.gz")

# 2.R built-in data - mtcars
head(mtcars)
                   mpg cyl disp  hp drat    wt  qsec vs am gear carb
Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2
Valiant           18.1   6  225 105 2.76 3.460 20.22  1  0    3    1

Visualization

1. Basic Plotting

1.1 Taking TCGA data as an example

# Data Preparation
counts <- table(TCGA_cli_df$T)
counts <- as.data.frame(counts)
names(counts)[names(counts) == "Var1"] <- "T"
# Calculate percentage
counts$fraction = counts$Freq / sum(counts$Freq)
# Calculate the cumulative percentage (the value at the top of each rectangle).
counts$ymax = cumsum(counts$fraction)
# Calculate the bottom of each rectangle to determine the starting position
counts$ymin = c(0, head(counts$ymax, n=-1))
# Plot
p <- ggplot(counts, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=T)) +
  geom_rect() +
  coord_polar(theta="y") + 
  xlim(c(2, 4)) 

p
Figureย 1: Taking TCGA data as an example

This donut chart describes the proportion of different tumor stages in the total sample.

1.2 Beautify plot

  • Use theme_void() to remove unnecessary backgrounds, axes, labels, etc.
  • Change the colors.
  • Donโ€™t use legends; add labels directly to the groups.
# Calculate percentage
counts$fraction = counts$Freq / sum(counts$Freq)
# Calculate the cumulative percentage (the value at the top of each rectangle).
counts$ymax = cumsum(counts$fraction)
# Calculate the bottom of each rectangle to determine the starting position
counts$ymin = c(0, head(counts$ymax, n=-1))
# Calculate label position
counts$labelPosition <- (counts$ymax + counts$ymin) / 2
# label Name
counts$label <- paste0(counts$T, "\n value: ", counts$Freq)
# Plot
p <- ggplot(counts, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=T)) +
  geom_rect() +
  geom_label( x=3.5, aes(y=labelPosition, label=label), size=6) + # This line of code controls the addition of labels to the chart, and removing it can delete labels.
  scale_fill_brewer(palette=4) +
  coord_polar(theta="y") +
  xlim(c(2, 4)) +
  theme_void() +
  theme(legend.position = "none")

p
Figureย 2: Beautify plot

This donut chart describes the proportion of different tumor stages in the total sample.

1.3 Take mtcars data as an example

# Data Preparation
counts1 <- table(mtcars$cyl)
counts1 <- as.data.frame(counts1)
names(counts1)[names(counts1) == "Var1"] <- "cyl"
counts1$fraction = counts1$Freq / sum(counts1$Freq)
counts1$ymax = cumsum(counts1$fraction)
counts1$ymin = c(0, head(counts1$ymax, n=-1))
counts1$labelPosition <- (counts1$ymax + counts1$ymin) / 2
counts1$label <- paste0(counts1$T, "\n value: ", counts1$Freq)
p <- ggplot(counts1, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=cyl)) +
  geom_rect() +
  coord_polar(theta="y") + 
  xlim(c(2, 4)) 

p
Figureย 3: Take mtcars data as an example

This donut chart describes the proportion of different cylinder numbers in the total sample.

2. Change the thickness of the ring

  • If xlim is set to a large left edge, there will be no empty rings. Youโ€™ll get a pie chart.
  • If xlim is set to a low value, the rings will be thinner.

2.1 Taking TCGA data as an example

p <- ggplot(counts, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=T)) +
  geom_rect() +
  geom_text( x=2, aes(y=labelPosition, label=label, color=T), size=6) + # X controls the label position.
  scale_fill_brewer(palette="Set1") +
  scale_color_brewer(palette="Set1") +
  coord_polar(theta="y") +
  xlim(c(-1, 4)) +
  theme_void() +
  theme(legend.position = "none")

p
Figureย 4: Taking TCGA data as an example

This donut chart describes the proportion of different tumor stages in the total sample.

2.2 Take mtcars data as an example

p <- ggplot(counts1, aes(ymax=ymax, ymin=ymin, xmax=4, xmin=3, fill=cyl)) +
  geom_rect() +
  geom_text( x=1.5, aes(y=labelPosition, label=label, color=cyl), size=6) + # X indicates whether the label position is inside or outside the loop.
  scale_fill_brewer(palette="Set2") +
  scale_color_brewer(palette="Set2") +
  coord_polar(theta="y") +
  xlim(c(-1, 4)) +
  theme_void() +
  theme(legend.position = "none")

p
Figureย 5: Take mtcars data as an example

This donut chart describes the proportion of different cylinder numbers in the total sample.

Applications

DonutApp1
Figureย 6: Applications of Donut Chart 1

This circular plot shows the distribution among clusters of human hippocampal scRNA-seq data. [1]

DonutApp2
Figureย 7: Applications of Donut Chart 2

This circular diagram shows the proportion of activated APs in the two types of neurons. [1]

Reference

[1] de Ceglia R, Ledonne A, Litvin DG, Lind BL, Carriero G, Latagliata EC, Bindocci E, Di Castro MA, Savtchouk I, Vitali I, Ranjak A, Congiu M, Canonica T, Wisden W, Harris K, Mameli M, Mercuri N, Telley L, Volterra A. Specialized astrocytes mediate glutamatergic gliotransmission in the CNS. Nature. 2023 Oct;622(7981):120-129. doi: 10.1038/s41586-023-06502-w. Epub 2023 Sep 6. PMID: 37674083; PMCID: PMC10550825.

[2] Huang KP, Acosta AA, Ghidewon MY, McKnight AD, Almeida MS, Nyema NT, Hanchak ND, Patel N, Gbenou YSK, Adriaenssens AE, Bolding KA, Alhadeff AL. Dissociable hindbrain GLP1R circuits for satiety and aversion. Nature. 2024 Aug;632(8025):585-593. doi: 10.1038/s41586-024-07685-6. Epub 2024 Jul 10. PMID: 38987598.

[3] Wickham, H. (2016). ggplot2: Elegant Graphics for Data Analysis. Springer-Verlag New York. https://ggplot2.tidyverse.org