0
votes

I'd like to show the mean value of each bar near the top of the bar plot a bit like the image below from this post.

image of correctly labeled bar plot

I'm using the geom_text code from that post, but the plot is placing the variable's values all over the bars rather than just one mean value per bar the top of the bar.

ggplot(data=SocratesPreStudyApproved, aes(x=PlatformOrder, y=ReflectiveReflectionTest, fill=PlatformOrder))+ 
  stat_summary(geom = "bar", fun = mean, position = "dodge", color="black")+
  stat_summary(geom = "errorbar", fun.data = mean_se, position = "dodge", width=.2)+
  stat_compare_means(method = "t.test", comparisons = PlatformComparisons, label = "p.signif")+
  facet_wrap(~ReasoningPhilosophyOrder, scales="fixed", strip.position = "bottom")+
  theme_classic()+
  theme(legend.position = "none")+
  labs(title = "Analyzing only approved participants (excluding rejected)",
       x = "Platform within each condition order",
       y = "Reflective responses to reasoning items (with lures)")+
  scale_fill_grey(start = .6, end = 1)+
  geom_text(aes(label = ReflectiveReflectionTest))

bar plot with numbers up the y-axis

Adding X and Y values for geom_text doesn't seem to help, e.g.,

geom_text(aes(x=PlatformOrder, y=ReflectiveReflectionTest, label = ReflectiveReflectionTest))

Question

How do I get just one numeric label per bar (that is the mean value of that bar, which is also the height of the bar on the y-axis)?

(I've installed and loaded all of the packages from the post, but not found a solution.)

1
Please add a reproducible dataset for us to better help you. Try the dput() function to help you get one. That said, the stat_summary() functions you are using do calculate a mean out of a range of values, but the geom_text() functions do not. In other words, geom_text() is plotting all observations. So you probably will need to add instructions calculate the mean you want to display as text. - Nicolás Velásquez
Thank you! This is helpful, as is Jon's answer - Nick Byrd

1 Answers

4
votes

Here's a simpler version of your question using a built-in data set.

ggplot(mtcars, aes(carb, wt, label = wt)) +
  stat_summary(geom = "bar", fun = mean, position = "dodge", color="black") +
  geom_text()

enter image description here

I've told the bar layer to calculate the mean wt and show that for each carb. Meanwhile, the text layer is receiving data for all the component elements and using their wt values as the y and label.

One option would be to make the text layer perform the same summary calculation.

ggplot(mtcars, aes(carb, wt, label = wt)) +
  stat_summary(geom = "bar", fun = mean, color="black") +
  # note: the ..y.. here tells ggplot to use the value after the summary calc
  stat_summary(aes(label=..y..), vjust = 0, geom = "text", fun = mean, color="black")

enter image description here

My personal preference would be to perform the summarization before ggplot, like this, resulting in a simpler plotting call for the same output:

mtcars %>%
  group_by(carb) %>%
  summarize(wt = mean(wt)) %>%
  ggplot(aes(carb, wt, label = wt)) +
  geom_col() +
  geom_text(vjust = 0)