I'm trying to add values at the top of my bars of a barchart with two groups. It works fine for values above zero. But I have also levels where there were no counts, so bars with the hight of 0. Then the text on top of the bar with counts is in the middle instead of right above the bar. And the place with count 0 has no indication.
Here's a data set:
vec.feed1.sorted <- c(rep(2,1), rep(3,2), rep(4,7), rep(5,15), rep(6,30), rep(7,40))
vec.feed1 <- sample(vec.feed1.sorted)
set.seed(001)
vec.feed1
df.feedback <- data.frame(
study = factor(c(rep(1,62),rep(2,33)), levels=c("1","2")),
feed1 = factor(vec.feed1, levels=as.character(c(1:7)))
)
df.feedback
And this is what I did so far:
ggplot(data = df.feedback,
aes(x = factor(feed1, levels = 1:7, labels = labels.feed1),
fill = factor(study))) +
geom_bar(aes(y = after_stat(count / ave(count, fill, FUN = sum))),
position = position_dodge(preserve="single")) +
scale_fill_manual(
values = c("grey40", "grey60"),
name = "event location",
labels = c("university", "cinema")) +
geom_text(aes(y = after_stat(count / ave(count, fill, FUN = sum)),
label = after_stat(scales::percent(count / ave(count, fill, FUN = sum), accuracy = 1))),
stat = "count", position = position_dodge(width=0.9), vjust = -0.5) +
ylab("percent of audience relative to location") +
xlab("How did you like this event?") +
theme(axis.text.x = element_text(angle = 45, hjust = .9)) +
#theme(axis.ticks.x = element_blank()) +
scale_y_continuous(labels = scales::percent, limits = c(0, 0.51)) +
scale_x_discrete(drop = FALSE) +
theme(
panel.border = element_rect(linetype = "solid", colour = "black", linewidth = .5, fill = NA),
panel.grid.minor = element_line(colour = "grey93", linewidth = .3),
panel.grid.major.y = element_line(colour = "grey93", linewidth = .3),
panel.background = element_rect(fill = "grey97")
) +
theme(axis.title.x.bottom = element_text(margin = margin(t = .15, unit = "in")))
This is the plot I get:
I would like to have the "2%" and "3%" right in the middle above the bar.
I would love if you could help me with this. Best, H.
You can use annotate
to manually add labels where you want.
library(tidyverse)
set.seed(001)
vec.feed1.sorted <- c(rep(2,1), rep(3,2), rep(4,7), rep(5,15), rep(6,30), rep(7,40))
vec.feed1 <- sample(vec.feed1.sorted)
df.feedback <- data.frame(
study = factor(c(rep(1,62),rep(2,33)), levels=c("1","2")),
feed1 = factor(vec.feed1, levels=as.character(c(1:7)))
)
ggplot(data = df.feedback,
aes(x = factor(feed1, levels = 1:7),
fill = factor(study))) +
geom_bar(aes(y = after_stat(count / ave(count, fill, FUN = sum))),
position = position_dodge(preserve="single")) +
scale_fill_manual(
values = c("grey40", "grey60"),
name = "event location",
labels = c("university", "cinema")) +
annotate('text',
x = c(1.8,2.8,3.8,4.2,4.8,5.2,5.8,6.2,6.8,7.2),
y = c(0.05,0.05,0.09,0.11,0.18,0.17,0.28,0.44,0.50,0.32),
label = c('3%','3%','6%','9%','16%','15%','26%','42%','48%','30%')) + # make adjustments to position and labels here
ylab("percent of audience relative to location") +
xlab("How did you like this event?") +
theme(axis.text.x = element_text(angle = 45, hjust = .9)) +
scale_y_continuous(labels = scales::percent, limits = c(0, 0.51)) +
scale_x_discrete(drop = FALSE) +
theme(
panel.border = element_rect(linetype = "solid", colour = "black", linewidth = .5, fill = NA),
panel.grid.minor = element_line(colour = "grey93", linewidth = .3),
panel.grid.major.y = element_line(colour = "grey93", linewidth = .3),
panel.background = element_rect(fill = "grey97")
) +
theme(axis.title.x.bottom = element_text(margin = margin(t = .15, unit = "in")))
Created on 2024-07-01 with reprex v2.1.0