Add number of observations per group in barplot (ggplot2)

Viewed 447

I am trying to add the number of observations to my plot, but I don't know if I am approaching this right. I drew a my plot using the ggplot2 and tidyverse packages.

What I want is to add the number of observations (in the Obs column of the data) on top of each of the columns of the graph. However, it looks like I am not doing it right because it takes the value for each part of the column.

Does anyone know how to solve this? Thank you very much!

Code for the graph

Euk_one %>% 
  drop_na(`Length Stretch`) %>%
  mutate_at(c("GGA","GGG","GGT","GGC"),~.x/`Length Stretch`) %>% 
  group_by(interval) %>% select(c(interval, "GGA","GGG","GGT","GGC", Obs))%>%
  summarize_all(mean) %>%pivot_longer(-c(interval, Obs)) %>%
  ggplot(aes(x=interval, y=value, fill=name)) + geom_col() +
  ggtitle("Eukarya 1 Codon Stretches - Distribution of codons ")+
  labs(fill= "Codons") +
  theme(axis.text.x = element_text(angle = 45)) + geom_text(aes(label=Obs), vjust = -.25)

Example Data

structure(list(interval = structure(c(2L, 2L, 2L, 2L, 2L, 2L, 
2L, 2L, 2L, 2L, 2L, 2L, 2L, 3L, 3L, 3L, 3L, 3L, 4L, 4L, 4L, 4L, 
4L, 4L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 
1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L, 1L), .Label = c("[6,7]", 
"(7,8]", "(8,9]", "(9,10]"), class = "factor"), `Length Stretch` = c(8, 
8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 
10, 10, 10, 6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 7, 6, 6, 6, 7, 
7, 6, 6, 7, 6, 6, 7, 7, 7, 6), GGA = c(0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 7, 0, 6, 0, 0, 0, 0, 0, 7, 6, 6, 0, 0, 0, 
0), GGG = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), GGT = c(8, 8, 8, 8, 8, 
8, 8, 8, 8, 8, 8, 8, 8, 9, 9, 9, 9, 9, 10, 10, 10, 10, 10, 10, 
6, 6, 6, 6, 6, 7, 6, 6, 6, 6, 6, 6, 0, 6, 0, 6, 7, 7, 6, 6, 0, 
0, 0, 7, 7, 7, 6), GGC = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), `Length Gene` = c(5250, 
5250, 3021, 1905, 2910, 2973, 2367, 3021, 2931, 2754, 2424, 2862, 
2436, 5061, 4935, 23949, 23988, 24024, 2733, 2733, 2358, 2358, 
2733, 2733, 2838, 2079, 2100, 1998, 2835, 1197, 1197, 2838, 1998, 
3795, 3795, 3795, 1320, 1827, 2088, 663, 10395, 10545, 2340, 
2340, 1323, 1977, 2085, 4773, 10557, 10554, 1920), NumGens = c(19297, 
19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 
19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 
19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 
19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 
19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 19297, 
19297, 19297, 19297, 19297, 19297), Count = c(1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 
1, 1, 1, 1), Obs = c(13L, 13L, 13L, 13L, 13L, 13L, 13L, 13L, 
13L, 13L, 13L, 13L, 13L, 5L, 5L, 5L, 5L, 5L, 6L, 6L, 6L, 6L, 
6L, 6L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 
27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 27L, 
27L, 27L, 27L)), class = "data.frame", row.names = c(NA, -51L
))

Example of the plot

enter image description here

1 Answers

As you have only one value to plot as a label per interval, you can filter your dataframe using distinct function from dplyr and set a single y value to plot it:

library(tidyverse)
Euk_one %>% 
  drop_na(`Length Stretch`) %>%
  mutate_at(c("GGA","GGG","GGT","GGC"),~.x/`Length Stretch`) %>% 
  group_by(interval) %>% dplyr::select(c(interval, "GGA","GGG","GGT","GGC", Obs))%>%
  summarize_all(mean) %>%pivot_longer(-c(interval, Obs)) %>%
  ggplot(aes(x=interval, y=value, fill=name)) + geom_col() +
  ggtitle("Eukarya 1 Codon Stretches - Distribution of codons ")+
  labs(fill= "Codons") +
  theme(axis.text.x = element_text(angle = 45)) + 
  geom_text(inherit.aes = FALSE, data = . %>% distinct(interval, Obs), 
            aes(x = interval, y = 0.25, label=Obs))

enter image description here

Does it answer your question ?

Related