0

I would like to add counts to a ggplot that uses stat_summary().

I am having an issue with the requirement that the text vector be the same length as the data.

With the examples below, you can see that what is being plotted is the same label multiple times.

The workaround to set the location on the y axis has the effect that multiple labels are stacked up. The visual effect is a bit strange (particularly when you have thousands of observations) and not sufficiently professional for my purposes. You will have to trust me on this one - the attached picture doesn't fully convey the weirdness of it.

I was wondering if someone else has worked out another way. It is for a plot in shiny that has dynamic input, so text cannot be overlaid in a hardcoded fashion.

I'm pretty sure ggplot wasn't designed for the kind of behaviour with stat_summary that I am looking for, and I may have to abandon stat_summary and create a new summary dataframe, but thought I would first check if someone else has some wizardry to offer up.

This is the plot without setting the y location:

library(dplyr)
library(ggplot2)


df_x <- data.frame("Group" = c(rep("A",1000), rep("B",2) ),
                   "Value" = rnorm(1002))
df_x <-  df_x %>%  
  group_by(Group) %>%
  mutate(w_count = n())
      

ggplot(df_x, aes(x = Group, y = Value)) +

    stat_summary(fun.data="mean_cl_boot", size = 1.2) +
    geom_text(aes(label = w_count)) +
    coord_flip() +
    theme_classic()


enter image description here

and this is with my hack


ggplot(df_x, aes(x = Group, y = Value)) +

    stat_summary(fun.data="mean_cl_boot", size = 1.2) +
    geom_text(aes(y = 1, label = w_count)) +
    coord_flip() +
    theme_classic()

enter image description here

2 Answers 2

2

Create a df_text that has the grouped info for your labels. Then use annotate:

library(dplyr)
library(ggplot2)

set.seed(123)

df_x <- data.frame("Group" = c(rep("A",1000), rep("B",2) ),
                   "Value" = rnorm(1002))

df_text <- df_x %>% 
  group_by(Group) %>% 
  summarise(avg = mean(Value),
            n = n()) %>%
  ungroup()

yoff <- 0.0
xoff <- -0.1

ggplot(df_x, aes(x = Group, y = Value)) +
  stat_summary(fun.data="mean_cl_boot", size = 1.2) +
  annotate("text", 
           x = 1:2 + xoff, 
           y = df_text$avg + yoff,
           label = df_text$n) +
  coord_flip() +
  theme_classic()

enter image description here

Sign up to request clarification or add additional context in comments.

Comments

1

I found another way which is a little more robust for when the plot is dynamic in its ordering and filtering, and works well for faceting. More robust, because it uses stat_summary for the text.

library(dplyr)
library(ggplot2)


df_x <- data.frame("Group" = c(rep("A",1000), rep("B",2) ),
                   "Value" = rnorm(1002))

counts_df <- function(y) {
  return( data.frame( y = 1, label = paste0('n=', length(y)) ) )
}


ggplot(df_x, aes(x = Group, y = Value)) +

    stat_summary(fun.data="mean_cl_boot", size = 1.2) +
    coord_flip() +
    theme_classic()

p + stat_summary(geom="text", fun.data=counts_df)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.