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).
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")
> 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