Reputation: 11
I am using the code:
age_pie_chart <- ggplot(data = data , aes(x = "", fill = `Q1: How old are you?`))+
geom_bar(position = "fill", width = 1) +
coord_polar(theta = "y") + xlab("") + ylab("") + blank_theme + scale_fill_grey()+
theme(axis.text.x=element_blank())
age_pie_chart
I want the percentage of each category to be added inside the chart. from searching I understand that I need to use geom_text function but before that I need to construct a frequency table with the percentage of the count of each category.
Upvotes: 1
Views: 1339
Reputation: 13863
Here's an example with some dummy data. First, here's the dummy data. I'm using sample()
to select values and then I'm ensuring we have a "small" slice by adding only 2 values for Q1 = "-15"
.
set.seed(1234)
data <- data.frame(
Q1 = c(sample(c('15-7','18-20','21-25'), 98, replace=TRUE), rep('-15', 2))
)
For the plot, it's basically the same as your plot, although you don't need the width
argument for geom_bar()
.
To get the text positioned correctly, you'll want to use geom_text()
. You could calculate the frequency before plotting, or you could have ggplot
calculate that on the fly much like it did for geom_bar
by using stat="count"
for your geom_text()
layer.
library(ggplot2)
ggplot(data=data, aes(x="", fill=Q1)) +
geom_bar(position="fill") +
geom_text(
stat='count',
aes(y=after_stat(..count..),
label=after_stat(scales::percent(..count../sum(..count..),1))),
position=position_fill(0.5),
) +
coord_polar(theta="y") +
labs(x=NULL, y=NULL) +
scale_fill_brewer(palette="Pastel1") +
theme_void()
So to be clear what's going on in that geom_text()
line:
I'm using stat="count"
. We want to access that counting statistic within the plot, so we need to specify to use that special stat function.
We are using ..count..
within the aesthetics. The key here is that in order to access the ..count..
value, we need the stat function to compute first. You can use the after_stat()
function to specify that the stat function should happen first before mapping the aesthetics - that opens ..count..
up to use for use within aes()
!
Percent calculation for the label. This happens via ..count../sum(..count..)
. I'm using scales::percent()
as a way to format the label as a percent.
Position = fill. Like the bar geom, we are also needing to use position="fill"
. You need to specify to use the actual position_fill()
method, since it allows us to access the vjust
argument. This positions each text value in the "middle" of each slice. If you just set position="fill"
, you get the text positioned at the edge of each slice.
Upvotes: 2