Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Are there any examples to avoid label overlap in pie chart? #149

Closed
shenweiyan opened this issue Mar 18, 2020 · 3 comments
Closed

Are there any examples to avoid label overlap in pie chart? #149

shenweiyan opened this issue Mar 18, 2020 · 3 comments
Labels

Comments

@shenweiyan
Copy link

I have a problem with labeling percent in pie charts. Some labels are overlapped since the space is not enough to distinctively show them.

@slowkow
Copy link
Owner

slowkow commented Mar 18, 2020

Annotate pie charts with ggrepel

Kamil Slowikowski
2020-03-18

Let’s make some data:

library(ggplot2)
df <- data.frame(
  group = c("Antelope", "Bird", "Cat", "Dog", "Eel"),
  value = c(25, 25, 50, 1, 1)
)
df
##      group value
## 1 Antelope    25
## 2     Bird    25
## 3      Cat    50
## 4      Dog     1
## 5      Eel     1
df$group <- factor(df$group, levels = rev(levels(df$group)))

Make a pie chart:

ggplot(df, aes(x = "", y = value, fill = group)) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y")

unnamed-chunk-2-1

Add labels with geom_text():

library(ggrepel)

window <- function(x) {
  n <- length(x)
  res <- vector(length = n - 1)
  for (i in seq(n - 1)) {
    res[i] <- (x[i] + x[i+1]) / 2
  }
  return(res)
}

df$pos <- window(cumsum(c(0, df$value)))

ggplot(df, aes(x = "", y = value, fill = group))+
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y", start = 0) +
  geom_text(aes(y = pos, x = 1.75, label = group)) +
  guides(fill = FALSE) +
  scale_fill_viridis_d() +
  theme_void()

unnamed-chunk-3-1

Or use geom_text_repel():

library(ggrepel)

window <- function(x) {
  n <- length(x)
  res <- vector(length = n - 1)
  for (i in seq(n - 1)) {
    res[i] <- (x[i] + x[i+1]) / 2
  }
  return(res)
}

df$pos <- window(cumsum(c(0, df$value)))

ggplot(df, aes(x = "", y = value, fill = group))+
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y", start = 0) +
  geom_text_repel(
    aes(y = pos, x = 1.5, label = group),
    size = 5, nudge_x = 0.2, min.segment.length = 1.25
  ) +
  guides(fill = FALSE) +
  scale_fill_viridis_d() +
  theme_void()

unnamed-chunk-4-1

sessionInfo()
## R version 3.6.1 (2019-07-05)
## Platform: x86_64-apple-darwin15.6.0 (64-bit)
## Running under: macOS Catalina 10.15.3
## 
## Matrix products: default
## BLAS:   /Users/kamil/miniconda3/lib/libmkl_rt.dylib
## LAPACK: /Library/Frameworks/R.framework/Versions/3.6/Resources/lib/libRlapack.0.dylib
## 
## locale:
## [1] en_US.UTF-8/en_US.UTF-8/en_US.UTF-8/C/en_US.UTF-8/en_US.UTF-8
## 
## attached base packages:
## [1] stats     graphics  grDevices utils     datasets  methods   base     
## 
## other attached packages:
## [1] ggrepel_0.8.2 ggplot2_3.3.0
## 
## loaded via a namespace (and not attached):
##  [1] Rcpp_1.0.4        knitr_1.28        magrittr_1.5      tidyselect_1.0.0 
##  [5] munsell_0.5.0     viridisLite_0.3.0 colorspace_1.4-1  R6_2.4.1         
##  [9] rlang_0.4.5       stringr_1.4.0     dplyr_0.8.5       tools_3.6.1      
## [13] grid_3.6.1        gtable_0.3.0      xfun_0.12         withr_2.1.2      
## [17] htmltools_0.4.0   assertthat_0.2.1  yaml_2.2.1        digest_0.6.25    
## [21] tibble_2.1.3      lifecycle_0.2.0   crayon_1.3.4      farver_2.0.3     
## [25] purrr_0.3.3       glue_1.3.2        evaluate_0.14     rmarkdown_2.1    
## [29] labeling_0.3      stringi_1.4.6     compiler_3.6.1    pillar_1.4.3     
## [33] scales_1.1.0      pkgconfig_2.0.3

@shenweiyan
Copy link
Author

It is really cool!

@olivroy
Copy link
Contributor

olivroy commented Apr 30, 2024

Is there a trick to do better with longer labels, to ensure they don't go inside the pie chart?

library(ggplot2)
df <- data.frame(
  group = c("Antelope", "Bird", "Cat a longer label", "Dog", "Eel a longer label"),
  value = c(25, 25, 50, 1, 1)
)
df
#>                group value
#> 1           Antelope    25
#> 2               Bird    25
#> 3 Cat a longer label    50
#> 4                Dog     1
#> 5 Eel a longer label     1
 df$group <- factor(df$group, levels = rev(df$group))

library(ggrepel)

window <- function(x) {
  n <- length(x)
  res <- vector(length = n - 1)
  for (i in seq(n - 1)) {
    res[i] <- (x[i] + x[i+1]) / 2
  }
  return(res)
}

df$pos <- window(cumsum(c(0, df$value)))

ggplot(df, aes(x = "", y = value, fill = group))+
  geom_bar(width = 1, stat = "identity") +
  coord_polar("y", start = 0) +
  geom_text_repel(
    aes(y = pos, x = 1.5, label = group),
    size = 5, nudge_x = 0.2, min.segment.length = 1.25
  ) +
  guides(fill = "none") +
  scale_fill_viridis_d() +
  theme_void()

Created on 2024-04-30 with reprex v2.1.0

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants