如何解决讨厌的饼形图箭头
让我们有以下代码:
pie_chart <- function(vec){
df <- as.data.frame(table(vec))
colnames(df)[1] <- 'group'
df$label <- paste0(df$Freq,' (',percent(df$Freq / sum(df$Freq)),')')
df$angle <- ((cumsum(df$Freq) - 0.5 * df$Freq) / sum(df$Freq) * 360) %% 180 - 90
ggplot(df,aes(x = "",y = Freq,fill = group)) +
geom_col(width = 1,show.legend = TRUE) +
geom_text(
aes(label = label,angle = angle),position = position_stack(vjust = 0.5),size = 5
) +
coord_polar("y",start = 0) +
theme_void()
}
pie_chart(c(rep(2,20),rep(3,30),rep(4,4),rep(5,50),rep(6,30)))
如上所示,文本居中(相对于饼图的每个部分)居中并旋转到圆圈的中间。
我想做的是将所有小于所有饼图的5%的值添加到箭头。因此,在我们的示例中,值“ 4(3.0)%”不应出现在饼图中,而应远超过箭头。
现在让我们研究我对该问题的研究:
pie_chart <- function(vec){
df <- as.data.frame(table(vec))
colnames(df)[1] <- 'group'
df$label <- paste0(df$Freq,angle = angle,x = ifelse(rev(Freq) / sum(Freq) < 0.05,1.7,1)),size = 5
) + geom_segment(aes(x = 1.6,xend = 1.5,y = rev(Freq)/2 + c(0,cumsum(rev(Freq))[-length(Freq)]),yend = after_stat(y),colour = I(ifelse(rev(Freq) / sum(Freq) < 0.05,"black","transparent"))),arrow = arrow(length = unit(1,"mm"))) +
coord_polar("y",30)))
正如您所看到的,我面临两个问题:
(1)布局崩溃(让我们看一下饼的红色部分)
(2)文本“ 4(3.0%)”在饼图上方,而不是与箭头连接(正确创建)
有什么办法可以解决问题(1)和(2)?
谢谢!
更新
按照SebSta的建议,我在他的代码中添加了箭头,它适用于这种特定情况。但是当我加上七个数字时,布局崩溃(我认为)
pie_chart <- function(vec){
df <- as.data.frame(table(vec))
colnames(df)[1] <- 'group'
df$label <- paste0(df$Freq,round(df$Freq / sum(df$Freq),3)*100,'%)')
df$angle <- ((cumsum(df$Freq) - 0.5 * df$Freq) / sum(df$Freq) * 360) %% 180 - 90
ggplot(df,color = ifelse(rev(df$Freq)/(sum(df$Freq))<0.05,"transparent","black"),size = 5
) + geom_segment(aes(x = 1.6,"mm"))) +
geom_text(aes(label =label,x =1.8),color = ifelse(rev(df$Freq)/(sum(df$Freq))>0.05,size = 5,) +
coord_polar("y",rep(7,3)))
解决方法
您可以使用position_identity
作为标签并计算出确切位置:
pie_chart <- function(vec){
df <- as.data.frame(table(vec))
colnames(df)[1] <- 'group'
df$label <- paste0(df$Freq,' (',scales::percent(df$Freq / sum(df$Freq)),')')
df$angle <- ((cumsum(df$Freq) - 0.5 * df$Freq) / sum(df$Freq) * 360) %% 180 - 90
ggplot(df,aes(x = "",y = Freq,fill = group)) +
geom_col(width = 1,show.legend = TRUE) +
geom_text(
aes(x = ifelse(Freq/sum(Freq) < 0.05,1.8,1),y = sum(Freq) - (cumsum(c(0,Freq[-length(Freq)])) + 0.5 * Freq),label = label,angle = angle),position = position_identity(),vjust = 0.25,size = 4
) + geom_segment(aes(x = 1.6,xend = 1.5,y = rev(Freq)/2 + c(0,cumsum(rev(Freq))[-length(Freq)]),yend = after_stat(y),colour = I(ifelse(rev(Freq) / sum(Freq) < 0.05,"black","transparent"))),arrow = arrow(length = unit(1,"mm"))) +
coord_polar("y",start = 0) +
theme_void()
}
pie_chart(c(rep(2,20),rep(3,30),rep(4,4),rep(5,50),rep(6,30)))
,
在这里,我的第一个想法将是一种不明智的做法:两次编写标签,一次是普通标签,所有值 5%都是透明的。然后,您可以使用x
坐标调整到饼图的距离:
pie_chart <- function(vec){
df <- as.data.frame(table(vec))
colnames(df)[1] <- 'group'
df$label <- paste0(df$Freq,round(df$Freq / sum(df$Freq),3)*100,'%)')
df$angle <- ((cumsum(df$Freq) - 0.5 * df$Freq) / sum(df$Freq) * 360) %% 180 - 90
ggplot(df,show.legend = TRUE) +
geom_text(
aes(label = label,color = ifelse(rev(df$Freq)/(sum(df$Freq))<0.05,"transparent","black"),position = position_stack(vjust = 0.5),size = 5
) +
geom_text(aes(label =label,angle = angle,x =1.8),color = ifelse(rev(df$Freq)/(sum(df$Freq))>0.05,size = 5,) +
coord_polar("y",30)))
请注意,我无法复制您的箭头,因为我没有after_stat
功能。我猜那是R 4.0.0的新版本,而我使用3.6.1。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。