ggplot pie chart labeling
Solution 1
For pie charts plotly works a lot easier than ggplot. Perhaps something like this:
library(plotly)
p <- plot_ly(alloc, labels = ~ltr, values = ~wght, type = 'pie',textposition = 'outside',textinfo = 'label+percent') %>%
layout(title = 'Letters',
xaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE),
yaxis = list(showgrid = FALSE, zeroline = FALSE, showticklabels = FALSE))
Solution 2
We can make it work with ggplot2
and the ggrepel
package.
Unfortunately geom_text_repel()
does not support a position =
argument, so we have to calculate the starting position of the line by hand.
With your data.frame
:
alloc$pos = (cumsum(c(0, alloc$wght)) + c(alloc$wght / 2, .01))[1:nrow(alloc)]
This calculates the mean point for each group (or obs, or whtvr you want to call it).
Plugging it in in the geom_text_repel
's y
aes
gives a nice result:
library(ggplot2)
library(ggrepel)
ggplot(alloc, aes(1, wght, fill = ltr)) +
geom_col(color = 'black',
position = position_stack(reverse = TRUE),
show.legend = FALSE) +
geom_text_repel(aes(x = 1.4, y = pos, label = ltr),
nudge_x = .3,
segment.size = .7,
show.legend = FALSE) +
coord_polar('y') +
theme_void()
I made some choices, as the use of text
instead of label
, the removal of the legend and the axes. Feel free to change them
Related videos on Youtube
AK88
Updated on June 14, 2022Comments
-
AK88 about 2 years
I am struggling with getting the pie chart labels correct. Looked around and thought that I could easily implement what mathematicalCoffee did. So far I have this code:
ltr = LETTERS[seq( from = 1, to = 26)] wght = runif(length(ltr)) wght = wght/sum(wght) wght = round(wght, digits = 2) alloc = as.data.frame(cbind(ltr, wght)) alloc$wght = as.numeric(as.character(alloc$wght)) ggpie <- function (dat, by, totals) { ggplot(dat, aes_string(x=factor(1), y=totals, fill=by)) + geom_bar(stat='identity', color='black') + guides(fill=guide_legend(override.aes=list(colour=NA))) + coord_polar(theta='y') + theme(axis.ticks=element_blank(), axis.text.y=element_blank(), axis.text.x=element_text(colour='black'), axis.title=element_blank()) + ## scale_fill_brewer(palette = "GnBu") + scale_y_continuous(breaks=cumsum(dat[[totals]]) - dat[[totals]] / 2, labels=paste(dat[[by]], ":", dat[[totals]])) } AA = ggpie(alloc, by = "ltr", totals = "wght") + ggtitle("Letter weights") AA
Is there any way to generate something like this, for example:
Update for suggested dup - I think that thread is more about alternatives to pie charts and why pie charts are bad. I would like to stick to pie charts and want to find a solution to handling labels correctly/user-friendly.
-
yeedle about 7 yearsPossible duplicate of beautiful Pie Charts with R
-
-
AK88 about 7 yearsAppreciate your response. Can you show any pie charts produced using
plotly
that give user-friendly labels? -
timfaber about 7 yearsCheck out the styled pie chart example in this reference: plot.ly/r/pie-charts Here you can set both labels/colors as well as define the label position.
-
AK88 about 7 yearsWell, it partially accomplishes what I am after. Let's say that pieces of the pie are really slim and multiple labels should be located outside the slice-area. Like in the example I provided above. Is
plotly
good at this? -
timfaber about 7 yearsHm not really sure, I believe labels are dodged whenever they overlap so it should cover this in case of superslim labels. There are annotate options in plotly that could deliver you the lines shown in your second example but I m afraid that would cost a lot of custom work.
-
timfaber about 7 yearsHa, I tried replacing ltr with
ltr = 1:150
to give this a go, rerunning the script gives you a pretty amazing pie but not sure if it's very readable -
AK88 about 7 yearsAlright, thanks. Will take a look at
plotly
after the weekend. -
AK88 about 7 yearsYes, that's the issue. I potentially will have around 30 pieces.
-
AK88 about 7 yearsAccepted. There doesn't seem to be a better alternative. Thank you.
-
sar over 4 yearsThis great, but I find the labels disappear off the top of the figure when I have a plot with small groups (eg. a=94, b=3, c=2, d=2). @timfaber