将带标签的饼图的标签段起点居中

centering the label segment starting points for labelled pie charts

我正在尝试使用 ggrepel 基于 创建带标签的饼图,但我似乎无法正确获取标签的位置。

理想情况下,我希望将标签连接到馅饼部分的部分从馅饼的中间开始,这样更美观。但这不是我得到的,我不确定我应该改变什么。我试过在 ggrepel 调用中设置 position = ggplot2::position_fill(vjust = 0.5),但这也无济于事。

数据

# setup
set.seed(123)
library(ggplot2)
library(ggrepel)
library(forcats)

# data
(df <- structure(
  list(
    cyl = structure(
      c(1L, 3L, 2L),
      .Label = c("8", "6", "4"),
      class = "factor"
    ),
    counts = c(14L, 11L, 7L),
    perc = c(43.75, 34.375, 21.875),
    label = c("44%", "34%", "22%")
  ),
  row.names = c(NA, -3L),
  class = c("tbl_df", "tbl", "data.frame")
))
#> # A tibble: 3 x 4
#>   cyl   counts  perc label
#>   <fct>  <int> <dbl> <chr>
#> 1 8         14  43.8 44%  
#> 2 4         11  34.4 34%  
#> 3 6          7  21.9 22%

函数

# function
foo <- function(df, x) {
  ggplot2::ggplot(
    data = df,
    mapping = ggplot2::aes(x = "", y = counts, fill = forcats::fct_inorder({{ x }}))
  ) +
    ggplot2::geom_bar(
      stat = "identity",
      color = "black",
      width = 1,
      na.rm = TRUE
    ) +
    coord_polar("y", start = 0) +
    ggrepel::geom_label_repel(
      aes(label = label),
      show.legend = FALSE,
      nudge_x = 1
    ) +
    guides(fill = guide_legend(title = rlang::as_name(rlang::ensym(x))))
}

情节

# plot
foo(df, cyl)

您可以手动计算标签的堆叠位置,而不是依赖 ggplot。查看以下内容是否适合您:

foo <- function(df, x) {
  df$y.label <- 0.5 * df$counts + rev(cumsum(dplyr::lag(rev(df$counts), default = 0)))
  ggplot2::ggplot(
    data = df,
    mapping = ggplot2::aes(x = "", y = counts, fill = forcats::fct_inorder({{ x }}))
  ) +
    ggplot2::geom_col(
      color = "black",
      width = 1,
      na.rm = TRUE
    ) +
    coord_polar("y", start = 0) +
    ggrepel::geom_label_repel(
      aes(label = label, y = y.label),
      show.legend = FALSE,
      nudge_x = 1
    ) +
    guides(fill = guide_legend(title = rlang::as_name(rlang::ensym(x))))
}

foo(df, cyl)