以下代码适用于短标签
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
这里不是摆弄
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
)
)