ggplot2饼图标签出现意外行为

9

我在这里检查了其他问题,但我没有看到这个问题。我有一个标记问题。奇怪的是,对于除一个标签之外的所有标签,代码都运行得很好。当我检查数据集时(这是一些非常简单的东西),一切似乎都很好(一个包含因子变量的列,另一个包含数字)。

这很奇怪,因为它可以正常处理具有相同结构的其他某些数据。然而,我已经尝试/检查了一切,但无法解决这个问题。以下是问题:

library(ggplot2)
library(ggrepel)

df = data.frame(
  status = c("Oak", "maple", "walnut", "Pine"),
  value = c( 47.54, 37.70, 11.48, 3.28))

ggplot(df, aes(x = "" , y = value, fill = fct_inorder(status))) +
  geom_bar(width = 1, stat = "identity") +
  coord_polar(theta = "y", start = 0 ) +
  scale_fill_brewer(palette = "Set3", direction = -4) +
  geom_label_repel(aes(label = paste0(value, "%")), size=4, show.legend = F, nudge_x = 1) +
  guides(fill = guide_legend(title = "Status")) +
  theme_void()

One of the labels came up with an issue

如果能给出至少一个建议或解释这个奇怪的行为,那就太好了。

显然,在新的 ggplot2 更新中,他们找到了位置问题的解决方法,而不需要提供任何额外的位置数据,但是,如果由于技术限制而无法使用它,则可能有所帮助以解决此类问题。


我认为问题在于geom_bar使用了position = "stack",但是geom_text_repel没有。添加position = "stack"可以解决这个问题。最好预先计算每个饼图切片的中点。 - Richard Telford
@RichardTelford 是的,这就是我尝试为geom_label_repel定义的内容,但是无论是它还是geom_text_repel都没有得到“position”的位置。不管怎样,谢谢。 - DSA
可能是ggplot,facet,piechart:将文本放置在饼图切片的中心的重复问题。 - Kamil Slowikowski
1个回答

9
我认为问题在于geom_bar(或更好的geom_col)默认为position=stack,而geom_text_repel则不是。将geom_text_repel设置为position="stack"会将标签放置在每个饼图部分的末尾而不是中点。
可以预先计算位置。下面的代码适用于所示数据,但可能不是通用的,因为它取决于行的顺序。
library(ggplot2)
library(ggrepel)

df = data.frame(
  status = c("Oak", "maple", "walnut", "Pine"),
  value = c( 47.54, 37.70, 11.48, 3.28))

df2 <- df %>% 
  mutate(
    cs = rev(cumsum(rev(value))), 
    pos = value/2 + lead(cs, 1),
    pos = if_else(is.na(pos), value/2, pos))

ggplot(df, aes(x = "" , y = value, fill = fct_inorder(status))) +
  geom_col(width = 1) +
  coord_polar(theta = "y", start = 0 ) +
  scale_fill_brewer(palette = "Set3", direction = -4) +
  geom_label_repel(aes(y = pos, label = paste0(value, "%")), data = df2, size=4, show.legend = F, nudge_x = 1) +
  guides(fill = guide_legend(title = "Status")) +
  theme_void()

嘿,非常感谢!这是一个简单数据集的快速解决方案,但它没有解释为什么其他代码在某些情况下有效,在这个数据集中却无法工作。此外,我们基本上是手动定义位置,如果我们想要控制位置,这实际上并不是非常实用。无论如何,非常感谢,对于简单子集来说这又是一个非常快速的解决方案。 - DSA
5
提醒一下,不需要手动计算标签的中点位置,可以使用“position = position_stack(vjust = .5)”将标签放在柱形图的中点。(但这里无法解决问题,因为“position_stack()”和“position_nudge()”不能同时使用。) - aosmith

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接