I am trying to generate a grouped barplot with percentage count on the y-axis and text on the top of each bar that represent its value
My code is below:
geom_bar(aes(y = (..count..)/sum(..count..) * 100), width = 0.7) +
labs(x = "Hours Worked 48 or more", y = "% of Employees", fill = "Hours Worked 48 or more", title = "Post-Legislation") +
theme_minimal() +
scale_fill_manual(values = c("orange", "blue")) +
geom_text(aes(label = (..count..)/sum(..count..) * 100, y = ..prop..), stat= "count", vjust = -.5) +
theme(legend.position = "top")
I want the text to be white, accurate to 1dp, and placed at the top of each bar.
I have been trying to different codes, but can't get the desired result.
Any help would be appreciated.
Here is the data snippet:
structure(list(year = c("2018", "2018", "2018", "2018", "2018",
"2018", "2018", "2018", "2018", "2018", "2018", "2018", "2018",
"2018", "2018", "2018", "2018", "2018", "2018", "2018", "2018",
"2018", "2018", "2018", "2018", "2018", "2018", "2018", "2018",
"2018"), hours.48 = c("Yes", "No", "No", "No", "Yes", "No", "No",
"No", "No", "No", "No", "No", "No", "No", "Yes", "No", "No",
"No", "No", "No", "No", "No", "No", "No", "No", "No", "No", "No",
"No", "No")), row.names = c(NA, 30L), class = "data.frame")
Try this:
library(tidyverse)
library(ggplot2)
positions = df %>% group_by(hours.48) %>% summarise(prop=n()/nrow(df)*100)
Note I am precomputing the labels = positions here. Given your example data, there aren't any decimals, but you can format the values you would like to see here if you want to go down this route. Personally, I prefer precomputing everything I want to plot to separate responsibilities.
ggplot(df, aes(x=hours.48, fill=hours.48)) +
geom_bar(aes(y = (..count..)/sum(..count..) * 100), width = 0.7) +
labs(x = "Hours Worked 48 or more", y = "% of Employees", fill = "Hours Worked 48 or more", title = "Post-Legislation") +
theme_minimal() +
scale_fill_manual(values = c("orange", "blue")) +
geom_text(data=positions, aes(label = prop, y = prop), colour='white', stat= "identity", vjust = 1) +
theme(legend.position = "top")
You can also simplify this even more by just querying positions
as dataframe instead of the original df
by using the following two lines instead of the corresponding ones above:
ggplot(positions, aes(x=hours.48, fill=hours.48)) +
geom_bar(aes(y = prop), width = 0.7, stat='identity') +