Search code examples
rggplot2pie-charttidyverse

pie chart labels not appearing properly only for certain facets


I am trying to create a pie chart with a number of facets, each with its own labels for percentages. It seems to work for certain datasets, while not for others. Below is a fully reproducible example of a dataset where the label positions are appropriate one facet (cyl: 4), but not for others (cyl: 6 and cyl: 8). For example, if you look at cyl: 6, slice with 57% has been labeled with the label for 43% and vice versa.

Anybody knows what's the origin of this behavior and how can I get rid of it?

library(dplyr)
library(datasets)
library(ggplot2)
data(mtcars)

# creating a dataframe
df <- dplyr::group_by(mtcars, .dots = c('cyl', 'am')) %>%
  dplyr::summarize(counts = n()) %>%
  dplyr::mutate(perc = (counts / sum(counts)) * 100) %>%
  dplyr::arrange(desc(perc))

# preparing the plot
ggplot2::ggplot(df, aes('', counts)) +
  geom_col(
    position = 'fill',
    color = 'black',
    width = 1,
    aes(fill = factor(am))
  ) +
  facet_wrap(~cyl, labeller = "label_both") +
  geom_label(
    aes(label = paste0(round(perc), "%"), group = factor(am)),
    position = position_fill(vjust = 0.5),
    color = 'black',
    size = 5,
    show.legend = FALSE
  ) +
  coord_polar(theta = "y")

Created on 2018-02-03 by the reprex package (v0.1.1.9000).


Solution

  • Update: As of the latest ggplot2 code base slated for release as ggplot2 2.3.0, this issue seems to be fixed. My old answer is retained below for archival purposes.

    library(dplyr)
    library(datasets)
    library(ggplot2)
    data(mtcars)
    
    # creating a dataframe
    df <- dplyr::group_by(mtcars, .dots = c('cyl', 'am')) %>%
      dplyr::summarize(counts = n()) %>%
      dplyr::mutate(perc = (counts / sum(counts)) * 100) %>%
      dplyr::arrange(desc(perc))
    
    # preparing the plot
    ggplot2::ggplot(df, aes('', counts)) +
      geom_col(
        position = 'fill',
        color = 'black',
        width = 1,
        aes(fill = factor(am))
      ) +
      facet_wrap(~cyl, labeller = "label_both") +
      geom_label(
        aes(label = paste0(round(perc), "%"), group = factor(am)),
        position = position_fill(vjust = 0.5),
        color = 'black',
        size = 5,
        show.legend = FALSE
      ) +
      coord_polar(theta = "y")
    

    Created on 2018-05-13 by the reprex package (v0.2.0).

    devtools::session_info()
    #> Session info -------------------------------------------------------------
    #>  setting  value                       
    #>  version  R version 3.5.0 (2018-04-23)
    #>  system   x86_64, darwin15.6.0        
    #>  ui       X11                         
    #>  language (EN)                        
    #>  collate  en_US.UTF-8                 
    #>  tz       America/Chicago             
    #>  date     2018-05-13
    #> Packages -----------------------------------------------------------------
    #>  package    * version    date       source                          
    #>  assertthat   0.2.0      2017-04-11 CRAN (R 3.5.0)                  
    #>  backports    1.1.2      2017-12-13 CRAN (R 3.5.0)                  
    #>  base       * 3.5.0      2018-04-24 local                           
    #>  bindr        0.1.1      2018-03-13 CRAN (R 3.5.0)                  
    #>  bindrcpp   * 0.2        2017-06-17 CRAN (R 3.5.0)                  
    #>  colorspace   1.4-0      2017-12-23 R-Forge (R 3.5.0)               
    #>  compiler     3.5.0      2018-04-24 local                           
    #>  curl         3.1        2017-12-12 CRAN (R 3.5.0)                  
    #>  datasets   * 3.5.0      2018-04-24 local                           
    #>  devtools     1.13.5     2018-02-18 CRAN (R 3.5.0)                  
    #>  digest       0.6.15     2018-01-28 CRAN (R 3.5.0)                  
    #>  dplyr      * 0.7.4      2017-09-28 CRAN (R 3.5.0)                  
    #>  evaluate     0.10.1     2017-06-24 CRAN (R 3.5.0)                  
    #>  ggplot2    * 2.2.1.9000 2018-05-12 local                           
    #>  glue         1.2.0      2017-10-29 CRAN (R 3.5.0)                  
    #>  graphics   * 3.5.0      2018-04-24 local                           
    #>  grDevices  * 3.5.0      2018-04-24 local                           
    #>  grid         3.5.0      2018-04-24 local                           
    #>  gtable       0.2.0      2016-02-26 CRAN (R 3.5.0)                  
    #>  htmltools    0.3.6      2017-04-28 CRAN (R 3.5.0)                  
    #>  httr         1.3.1      2017-08-20 CRAN (R 3.5.0)                  
    #>  knitr        1.20       2018-02-20 CRAN (R 3.5.0)                  
    #>  labeling     0.3        2014-08-23 CRAN (R 3.5.0)                  
    #>  lazyeval     0.2.1      2017-10-29 CRAN (R 3.5.0)                  
    #>  magrittr     1.5        2014-11-22 CRAN (R 3.5.0)                  
    #>  memoise      1.1.0      2017-04-21 CRAN (R 3.5.0)                  
    #>  methods    * 3.5.0      2018-04-24 local                           
    #>  mime         0.5        2016-07-07 CRAN (R 3.5.0)                  
    #>  munsell      0.4.3      2016-02-13 CRAN (R 3.5.0)                  
    #>  pillar       1.2.1      2018-02-27 CRAN (R 3.5.0)                  
    #>  pkgconfig    2.0.1      2017-03-21 CRAN (R 3.5.0)                  
    #>  plyr         1.8.4      2016-06-08 CRAN (R 3.5.0)                  
    #>  R6           2.2.2      2017-06-17 CRAN (R 3.5.0)                  
    #>  Rcpp         0.12.16    2018-03-13 CRAN (R 3.5.0)                  
    #>  rlang        0.2.0.9001 2018-05-10 Github (r-lib/rlang@ccdbd8b)    
    #>  rmarkdown    1.9        2018-03-01 CRAN (R 3.5.0)                  
    #>  rprojroot    1.3-2      2018-01-03 CRAN (R 3.5.0)                  
    #>  scales       0.5.0.9000 2018-04-10 Github (hadley/scales@d767915)  
    #>  stats      * 3.5.0      2018-04-24 local                           
    #>  stringi      1.1.7      2018-03-12 CRAN (R 3.5.0)                  
    #>  stringr      1.3.0      2018-02-19 CRAN (R 3.5.0)                  
    #>  tibble       1.4.2      2018-01-22 CRAN (R 3.5.0)                  
    #>  tools        3.5.0      2018-04-24 local                           
    #>  utils      * 3.5.0      2018-04-24 local                           
    #>  withr        2.1.2      2018-05-10 Github (jimhester/withr@79d7b0d)
    #>  xml2         1.2.0      2018-01-24 CRAN (R 3.5.0)                  
    #>  yaml         2.1.18     2018-03-08 CRAN (R 3.5.0)
    

    Old answer

    Seems like geom_col() in ggplot2_2.2.1.9000 cares about the order of the data in the data frame. This works:

    library(dplyr)
    library(datasets)
    library(ggplot2)
    data(mtcars)
    
    # creating a dataframe
    df <- dplyr::group_by(mtcars, .dots = c('cyl', 'am')) %>%
      dplyr::summarize(counts = n()) %>%
      dplyr::mutate(perc = (counts / sum(counts)) * 100) %>%
      dplyr::arrange(cyl, desc(am)) # change in the code is here, I'm sorting by cyl and am, not by perc
    
    # preparing the plot
    ggplot2::ggplot(df, aes('', counts)) +
      geom_col(
        position = 'fill',
        color = 'black',
        width = 1,
        aes(fill = factor(am))
      ) +
      facet_wrap(~cyl, labeller = "label_both") +
      geom_label(
        aes(label = paste0(round(perc), "%"), group = factor(am)),
        position = position_fill(vjust = 0.5),
        color = 'black',
        size = 5,
        show.legend = FALSE
      ) +
      coord_polar(theta = "y")
    

    enter image description here

    > sessionInfo()
    R version 3.4.2 (2017-09-28)
    Platform: x86_64-apple-darwin15.6.0 (64-bit)
    Running under: macOS Sierra 10.12.6
    
    Matrix products: default
    BLAS: /System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/libBLAS.dylib
    LAPACK: /Library/Frameworks/R.framework/Versions/3.4/Resources/lib/libRlapack.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] bindrcpp_0.2       ggplot2_2.2.1.9000 dplyr_0.7.4