外部带有 ggplot2 / ggrepel 长标签的饼图

问题描述 投票:0回答:1

以下代码适用于短标签

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()

但是正如您所看到的,长标签最终出现在饼图中

有没有办法调整代码以确保所有标签最终都在外面?

C/F https://github.com/slowkow/ggrepel/issues/149#issuecomment-2086233775

r ggplot2 ggrepel
1个回答
0
投票

这里不是摆弄

ggrepel
,而是使用
coord_radial
引入的新
ggplot2 3.5.0
而不是
coord_polar
,通过轴文本添加注释,并仅将
ggrepel
用于需要排斥的标签。 .

注意:如果您想坚持使用

ggrepel
,我建议使用两个单独的层,因为您必须将长标签微移更大的量才能将其移到饼图之外。

library(ggrepel)
library(ggplot2)

df$pos <- .5 * (
  cumsum(c(0, df$value[-length(df$value)])) +
    cumsum(df$value)
)

ggplot(df, aes(x = "", y = value, fill = group)) +
  geom_bar(width = 1, stat = "identity") +
  coord_radial("y", start = 0, clip = "off", expand = FALSE) +
  geom_text_repel(
    data = ~ subset(.x, group %in% c("Dog", "Eel a longer label")),
    aes(
      y = pos,
      x = 1.5,
      label = group
    ),
    size = 5, min.segment.length = 1.25,
    nudge_x = .2,
    direction = "x"
  ) +
  scale_y_continuous(
    breaks = df$pos[!df$group %in% c("Dog", "Eel a longer label")],
    labels = df$group[!df$group %in% c("Dog", "Eel a longer label")]
  ) +
  guides(fill = "none") +
  scale_fill_viridis_d() +
  theme_void() +
  theme(
    axis.text.x = element_text(
      size = 5 * .pt
    )
  )

enter image description here

© www.soinside.com 2019 - 2024. All rights reserved.