# stacked bargraph with error bars

I'm attempting to plot a stacked barplot with ggplot2 with this code:

ggplot(CC, aes(x = Condition, y = Percent, fill = Cell_Cycle))+
geom_bar(stat = "identity")+
geom_text(aes(label = paste(round(Percent,2),"%")), position = position_stack(vjust =  0.5))


Question: How do I go about adding error bars to the graph?

I tried this code:

ggplot(DF, aes(x = Condition, y = Percent, fill = Cell_Type))+
geom_bar(stat = "identity")+
geom_text(aes(label = paste(round(Percent,2),"%")), position = position_stack(vjust =  0.5) + geom_errorbar(aes(ymin=Condition, ymax=Condition), width = .2))


But got this error:

Error: Cannot add ggproto objects together.

output of dput(DF)

structure(list(Cell_Type = structure(c(1L, 2L, 3L, 4L, 5L, 6L,
7L, 1L, 2L, 3L, 4L, 5L, 6L, 7L), .Label = c("Fibroblast", "T cell",
"Macrophage", "Tumor", "Islets of Langerhans", "Endothelial",
"B cell"), class = "factor"), Condition = structure(c(1L, 1L,
1L, 1L, 1L, 1L, 1L, 2L, 2L, 2L, 2L, 2L, 2L, 2L), .Label = c("treated",
"untreated"), class = "factor"), Freq = c(6051L, 1892L, 1133L,
657L, 116L, 868L, 832L, 5331L, 3757L, 1802L, 835L, 287L, 704L,
256L), Percent = c(52.3941466793662, 16.3823707680319, 9.8103731924842,
5.68880422547407, 1.00441596675037, 7.51580223395965, 7.20408693393367,
41.0962072155412, 28.9623805118717, 13.8914585260561, 6.43694110391613,
2.21245760098674, 5.42707369719396, 1.97348134443417)), class = c("grouped_df",
"tbl_df", "tbl", "data.frame"), row.names = c(NA, -14L), groups = structure(list(
Condition = structure(1:2, .Label = c("treated", "untreated"
), class = "factor"), .rows = list(1:7, 8:14)), row.names = c(NA,
-2L), class = c("tbl_df", "tbl", "data.frame"), .drop = TRUE))

• What are len and sd ? can you add a reproducible example of DF, len,sd ? By curiosity, does your question is related to this one bioinformatics.stackexchange.com/questions/11197/…? – dc37 Jan 23 '20 at 16:44
• I didn't change len and sd when I pasted it. I have updated it to Condition and added the output of DF. And yes, it is related to that question. Wasn't sure whether to ask it on the same question. – user6810 Jan 23 '20 at 16:51
• In your exemple, there is no mention of len and sd, so it is not clear what are these values and how you want to calculate them. Also, does the related question is yours ? because you don't have the same username ? – dc37 Jan 23 '20 at 17:02
• len and sd are not part of my example. When I pasted the code to the question, I didn't change it. Yes, it is my question, as for the username, I just created a new account as I couldn't log into the other. – user6810 Jan 23 '20 at 17:05
• Ok, so your question is about to calculate len and sd ? because you don't have these values, right ? For your account, you can see this link: bioinformatics.stackexchange.com/help/merging-accounts. Also, when you are registered on one site of StackExchange, you can directly create a new account on another StackExchange website by clicking on topright join Community button, it will automatically link your account on all sites you are registered of. – dc37 Jan 23 '20 at 17:13

If you want to indicate the error or the uncertainty for each cell type, you need to replicate your experiments, ccount each cell type in each replicate, calculate the average percentage of each cell type in each condition and the associated standard deviation.

To answer your question about how to plot a stacked bargraph with error bar, first this option is not integrated into ggplot2 (see this discussion from the creator of ggplot2: https://github.com/tidyverse/ggplot2/issues/1079)

So, you need to calculate the position of each error bar by hand. You can do that by using dplyr. Here, I set the same error bar for everyone as you don't know what is the standard deviation in your data but at least you can observe the structure of the dataframe:

library(dplyr)
library(ggplot2)
DF %>% mutate(SD = 2) %>%
mutate(Cell_Type = factor(Cell_Type, levels = c("B cell","Endothelial","Islets of Langerhans","Tumor","Macrophage","T cell","Fibroblast"))) %>%
group_by(Condition) %>%
mutate(SDPos = cumsum(Percent)) %>%
ggplot(aes(x = Condition, y = Percent, fill = Cell_Type))+
geom_bar(stat = "identity")+
geom_text(aes(label = paste(round(Percent,2),"%")), position = position_stack(vjust =  0.5))+
geom_errorbar(aes(ymin = SDPos-SD, ymax = SDPos+SD), width = 0.3, position = "identity")


As you can see, it's pretty ugly... so, if you need to add error bar, I will rather advised you to do a dodged barchart as the following:

library(dplyr)
library(ggplot2)
DF %>% mutate(SD = 2) %>%
ggplot(aes(x = Cell_Type, y = Percent, fill = Condition))+
geom_bar(stat = "identity", position = position_dodge())+
geom_text(aes(label = paste(round(Percent,2),"%")), position = position_dodge(0.9), vjust =-2, size = 3)+
geom_errorbar(aes(ymin = Percent-SD, ymax = Percent+SD), width = 0.3, position = position_dodge(0.9))+
theme(axis.text.x = element_text(angle = 45, hjust = 1))+
scale_y_continuous(limits = c(-2,60))


To my opinion, it makes easier the comparison of the distribution of each cell type between conditions.

• I agree if you are able to have more than 3 replicates. Otherwise, the spread observed with boxplot or violin plot won't mean a lot. But as it seems that individual values are the count of different cell types from single cell RNA seq, I doubt you can have a lot of replicates. That's why I advised for barchart. But it is also possible to plot individual values and the mean using geom_pointrange. – dc37 Jan 23 '20 at 20:57