I have a bar graph with positive and negative values, and want to have the value labels just outside each bar (i.e., above the bars with positive values and below the bars with negative values). However, I can only either get them to be right at the edge of the bar (where it is unreadable), or all value labels adjusted upward (which looks strange for the negative values).[Figure 1]([[Figure 2] https://i.stack.imgur.com/zc7zf.jpg)].
The code I’ve tried:
<code>ggplot(data = data, mapping = aes(x = IV, y = DV, fill = Mod)) +
stat_summary(fun.data = mean_sdl, geom = "bar", position = position_dodge(), color = "black") +
theme(text = element_text(family = "Arial")) +
labs(y = "Dependent Variable") +
theme(plot.title = element_text(hjust = 0.5, vjust = -3, size = 25, face = 'bold'), axis.title = element_text(size = 15, face = "bold"),
axis.text.x = element_text(size = 15), axis.text.y = element_text(size = 15), legend.position = "right") +
scale_x_discrete("Factor 1", labels = c("Level 1","Level 2", "Level 3")) + # Needs this variable to be a FACTOR
scale_fill_manual(values = c("#9a0000", "#02029883"), name = "Factor 1", breaks = c("0","1"), labels = c("Level 1","Level 3")) +
coord_cartesian(ylim = c(-1, 1)) +
scale_y_continuous(breaks = c(-1, 0, 1)) +
stat_summary(fun.data = mean_se, geom = "errorbar", width=0.3, position = position_dodge(.9)) +
stat_summary(aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = -4, position = position_dodge(0.9)) +
geom_segment(aes(x = 0, xend = 3, y = 0, yend = 0))
<code>ggplot(data = data, mapping = aes(x = IV, y = DV, fill = Mod)) +
stat_summary(fun.data = mean_sdl, geom = "bar", position = position_dodge(), color = "black") +
theme_classic() +
theme(text = element_text(family = "Arial")) +
labs(y = "Dependent Variable") +
theme(plot.title = element_text(hjust = 0.5, vjust = -3, size = 25, face = 'bold'), axis.title = element_text(size = 15, face = "bold"),
axis.text.x = element_text(size = 15), axis.text.y = element_text(size = 15), legend.position = "right") +
scale_x_discrete("Factor 1", labels = c("Level 1","Level 2", "Level 3")) + # Needs this variable to be a FACTOR
scale_fill_manual(values = c("#9a0000", "#02029883"), name = "Factor 1", breaks = c("0","1"), labels = c("Level 1","Level 3")) +
coord_cartesian(ylim = c(-1, 1)) +
scale_y_continuous(breaks = c(-1, 0, 1)) +
stat_summary(fun.data = mean_se, geom = "errorbar", width=0.3, position = position_dodge(.9)) +
stat_summary(aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = -4, position = position_dodge(0.9)) +
geom_segment(aes(x = 0, xend = 3, y = 0, yend = 0))
</code>
ggplot(data = data, mapping = aes(x = IV, y = DV, fill = Mod)) +
stat_summary(fun.data = mean_sdl, geom = "bar", position = position_dodge(), color = "black") +
theme_classic() +
theme(text = element_text(family = "Arial")) +
labs(y = "Dependent Variable") +
theme(plot.title = element_text(hjust = 0.5, vjust = -3, size = 25, face = 'bold'), axis.title = element_text(size = 15, face = "bold"),
axis.text.x = element_text(size = 15), axis.text.y = element_text(size = 15), legend.position = "right") +
scale_x_discrete("Factor 1", labels = c("Level 1","Level 2", "Level 3")) + # Needs this variable to be a FACTOR
scale_fill_manual(values = c("#9a0000", "#02029883"), name = "Factor 1", breaks = c("0","1"), labels = c("Level 1","Level 3")) +
coord_cartesian(ylim = c(-1, 1)) +
scale_y_continuous(breaks = c(-1, 0, 1)) +
stat_summary(fun.data = mean_se, geom = "errorbar", width=0.3, position = position_dodge(.9)) +
stat_summary(aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = -4, position = position_dodge(0.9)) +
geom_segment(aes(x = 0, xend = 3, y = 0, yend = 0))
I’ve tried several iterations with geom_text() but since I want to display a label of the mean, it shows all observations instead of one.
Based on other similar questions on SO, I’ve tried several alternatives. E.g., instead of:
<code>stat_summary(aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, position = position_dodge(0.9)) +
<code>stat_summary(aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, position = position_dodge(0.9)) +
</code>
stat_summary(aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, position = position_dodge(0.9)) +
I’ve also tried:
<code> geom_label(aes(label = round(mean(DV), digits = 0), segment.colour = NA)) +
<code> geom_label(aes(label = round(mean(DV), digits = 0), segment.colour = NA)) +
</code>
geom_label(aes(label = round(mean(DV), digits = 0), segment.colour = NA)) +
<code>geom_text(aes(mean_IV = mean_IV + sign(mean_IV),label = mean_IV)) +
<code>geom_text(aes(mean_IV = mean_IV + sign(mean_IV),label = mean_IV)) +
</code>
geom_text(aes(mean_IV = mean_IV + sign(mean_IV),label = mean_IV)) +
<code> geom_text(aes(label = round(..y.., 2), fun.y = mean, vjust = place), size = 4, fontface = "bold", family = "Fira Sans") +
<code> geom_text(aes(label = round(..y.., 2), fun.y = mean, vjust = place), size = 4, fontface = "bold", family = "Fira Sans") +
</code>
geom_text(aes(label = round(..y.., 2), fun.y = mean, vjust = place), size = 4, fontface = "bold", family = "Fira Sans") +
<code>stat_summary(data = . %>% filter(mean(zEng) >= 0), aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = -5, position = position_dodge(0.9)) +
stat_summary(data = . %>% filter(mean(zEng) < 0), aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = 5, position = position_dodge(0.9)) +
<code>stat_summary(data = . %>% filter(mean(zEng) >= 0), aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = -5, position = position_dodge(0.9)) +
stat_summary(data = . %>% filter(mean(zEng) < 0), aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = 5, position = position_dodge(0.9)) +
</code>
stat_summary(data = . %>% filter(mean(zEng) >= 0), aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = -5, position = position_dodge(0.9)) +
stat_summary(data = . %>% filter(mean(zEng) < 0), aes(label = round(..y.., 2)), fun.y = mean, geom = "text", family = "Arial", size = 3, vjust = 5, position = position_dodge(0.9)) +
<code># geom_text(aes(label = round(..y.., 2), fun.y = mean, vjust = ifelse(fun.y >= 0, 0, 1))) +
<code># geom_text(aes(label = round(..y.., 2), fun.y = mean, vjust = ifelse(fun.y >= 0, 0, 1))) +
</code>
# geom_text(aes(label = round(..y.., 2), fun.y = mean, vjust = ifelse(fun.y >= 0, 0, 1))) +
and
<code>vjust = ifelse(..y.. >= 0, 1, -1)
<code>vjust = ifelse(..y.. >= 0, 1, -1)
</code>
vjust = ifelse(..y.. >= 0, 1, -1)