Reputation: 4889
I am trying to create a labelled pie chart using ggrepel
based on a StackOverflow answer, but I can't seem to get the position of the labels correctly.
Ideally, I would like the segments that connect the labels to the portion of the pies to start in the middle of the pie for it to be more aesthetically pleasing. But this is not what I get, and I am not sure what I should be changing. I have tried setting position = ggplot2::position_fill(vjust = 0.5)
in ggrepel
call, but that doesn't help either.
# 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)
Upvotes: 2
Views: 240
Reputation: 29095
You can calculate the labels' stacked positions manually, instead of relying on ggplot. See if the following works for you:
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)
Upvotes: 1