I'm trying to produce a stacked column chart with data labels.
I'm able to produce the chart, but was unable to find a way to input data labels. I have tried geom_text()
but it keeps asking me to input a y label (which if you see the ggplot code is not there). I have also tried adding geom_text(stat = "count")
but that also gives me an error saying
"Error: geom_text requires the following missing aesthetics: y and label".
PS - i'm aware I need to rename the y axis as percentage. I'm also trying to figure out how to have more contrasting colours
ggplot(property,
aes(x=Bedrooms.New, fill=Property.Type.)) +
geom_bar(position = "fill") +
scale_x_discrete(name = "Number of Bedrooms",
limits = sort(factor(unique(property$Bedrooms.New))))
I have added an image below to see what my output is right now!
As the error message is telling you, geom_text
requires the label
aes. In your case you want to label the bars with a variable which is not part of your dataset but instead computed by stat="count"
, i.e. stat_count
.
The computed variable can be accessed via ..NAME_OF_COMPUTED_VARIABLE..
. , e.g. to get the counts use ..count..
as variable name. BTW: A list of the computed variables can be found on the help package of the stat or geom, e.g. ?stat_count
UPDATE: The dot-dot notation was deprecated in ggplot2 3.4.0
. Instead we could or should use after_stat
, i.e. use e.g. after_stat(count)
instead of ..count..
Using mtcars
as an example dataset you can label a geom_bar
like so:
library(ggplot2)
ggplot(mtcars, aes(cyl, fill = factor(gear))) +
geom_bar(position = "fill") +
geom_text(aes(label = after_stat(count)),
stat = "count", position = "fill"
)
Two more notes:
To get the position of the labels right you have to set the position
argument to match the one used in geom_bar
, e.g. position="fill"
in your case.
While counts are pretty easy, labelling with percentages is a different issue. By default stat_count
computes percentages by group, e.g. by the groups set via the fill
aes. These can be accessed via after_stat(prop)
. If you want the percentages to be computed differently, you have to do it manually.
As an example if you want the percentages to sum to 100% per bar this could be achieved using after_stat
and ave
(to compute the percentage per group) like so:
library(ggplot2)
ggplot(mtcars, aes(cyl, fill = factor(gear))) +
geom_bar(position = "fill") +
geom_text(
aes(label = after_stat(
scales::percent(
ave(count, x, FUN = function(x) x / sum(x))
)
)),
stat = "count", position = "fill"
)