Let's have the code following :
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)))
As you can see above, text is centered (with respect to each part of pie) and rotated to the middle of circle.
What I want to do is to add the arrow all values less than 5% of all pie chart. So in our example value '4(3.0)%' should not be in pie chart but it should be outstide followed by arrow.
Let's now study my research about the problem :
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, x = ifelse(rev(Freq) / sum(Freq) < 0.05, 1.7, 1)),
position = position_stack(vjust = 0.5),
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", start = 0) +
theme_void()
}
pie_chart(c(rep(2,20),rep(3,30),rep(4,4),rep(5,50),rep(6,30)))
And as you can see I'm facing two problems :
(1) The layout crashed (let's have a look at red part of pie)
(2) text '4(3.0%)' is above pie chart instead being connected with arrow (which is created properly)
Is there any way to solve problems (1) and (2) ?
Thanks in advance!
UPDATE
As SebSta proposed, I used his code with added arrows and it works for this specific case. But when I add three sevens the layout crashes (in my opinion)
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, aes(x = "", y = Freq, fill = group)) +
geom_col(width = 1, show.legend = TRUE) +
geom_text(
aes(label = label, angle = angle), color = ifelse(rev(df$Freq)/(sum(df$Freq))<0.05, "transparent", "black"),
position = position_stack(vjust = 0.5),
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"))) +
geom_text(aes(label =label, angle = angle, x =1.8),
color = ifelse(rev(df$Freq)/(sum(df$Freq))>0.05, "transparent", "black"),
size = 5,position = position_stack(vjust = 0.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),rep(7,3)))