<p>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.</p>

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

<p>So, you need to calculate the position of each error bar by hand. You can do that by using <code>dplyr</code>. 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:</p>

<pre class="lang-r prettyprint-override"><code>library(dplyr)
library(ggplot2)
DF %&gt;% mutate(SD = 2) %&gt;%
  mutate(Cell_Type = factor(Cell_Type, levels = c("B cell","Endothelial","Islets of Langerhans","Tumor","Macrophage","T cell","Fibroblast"))) %&gt;%
  group_by(Condition) %&gt;%
  mutate(SDPos = cumsum(Percent)) %&gt;%
  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")
</code></pre>

<p><a href="https://i.sstatic.net/Bn98R.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/Bn98R.png" alt="enter image description here"></a></p>

<p>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:</p>

<pre class="lang-r prettyprint-override"><code>library(dplyr)
library(ggplot2)
DF %&gt;% mutate(SD = 2) %&gt;%
  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))
</code></pre>

<p><a href="https://i.sstatic.net/M22VR.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/M22VR.png" alt="enter image description here"></a></p>

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

<p>Hope that it answers your question.</p>

CC BY-SA 4.0
2020-01-23T20:31:40.187Z
For this scenario, I would advise against a barchart and would use a violin plot or a boxplot instead. The latter two would enable to assess the number of replicates within a group as well as the spread of the replicates.
haci
CC BY-SA 4.0
2020-01-23T20:57:52.867Z
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
CC BY-SA 4.0
2020-01-23T21:47:16.697Z
These numbers and graphs will not mean anything anyway if one does not have many replicates, especially if the data are from human samples and not from a model organism with a rather "clean" genetic background. Moreover, it is even more important to use box/violin plots when the number of replicates are small so that the reader is not mislead about the lack of power in the analyses. I guess, at least hope, that we will not see these plots in the future anyway: https://twitter.com/rafalab/status/1098973538260840449?lang=en
haci
CC BY-SA 4.0
2020-01-23T22:01:55.490Z
Totally agree ;) and personally, I won't publish those kind of results (at least in this format). But it's well beyond the scope of the question :D
dc37
CC BY-SA 4.0
2020-01-24T13:17:37.050Z
These samples are derived from human samples, and I have replicates for each sample. A total of 32 samples, 16 from each condition. What do you all propose I should use to plot? I'm new at bioinformatics, and assumed a bargraph would be ideal. From reading the comments and answer, I don't have SD for each. I will add that.
user6810
CC BY-SA 4.0
2020-01-24T15:59:10.183Z
If you have 16 for each conditions, you should associate them in a single dataframe and plot a boxplot or a violin plot as advised by @haci.
dc37
CC BY-SA 4.0
2020-01-23T19:52:00.803Z
2020-01-23T20:00:13.053Z
2020-01-23T20:00:13.053Z
dc37
<p>I'm attempting to plot a stacked barplot with ggplot2 with this code:</p>

<pre class="lang-r prettyprint-override"><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))
</code></pre>

<p><a href="https://i.sstatic.net/YTjJJ.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/YTjJJ.png" alt="stacked bar graph"></a></p>

<p>Question: How do I go about adding error bars to the graph?</p>

<p>I tried this code:</p>

<pre class="lang-r prettyprint-override"><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))
</code></pre>

<p>But got this error: </p>

<blockquote>
  <p>Error: Cannot add ggproto objects together.</p>
</blockquote>

<p>output of dput(DF)</p>

<pre><code>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))
</code></pre>

CC BY-SA 4.0
2020-01-23T16:44:34.187Z
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 https://bioinformatics.stackexchange.com/questions/11197/stacked-barplot-for-single-cell-analysis?
dc37
CC BY-SA 4.0
2020-01-23T16:51:11.523Z
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
CC BY-SA 4.0
2020-01-23T17:02:09.123Z
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
CC BY-SA 4.0
2020-01-23T17:05:46.940Z
`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
CC BY-SA 4.0
2020-01-23T17:13:09.157Z
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: https://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
CC BY-SA 4.0
2020-01-23T17:20:20.173Z
You are getting `Error: Cannot add ggproto objects together.` because you lack a `)` and `geom_text()` is not closed. And once this is fixed, you would get `Error: Discrete value supplied to continuous scale` because `geom_errorbar()` is for intervals but your `Condition` variable is a factor.
haci
CC BY-SA 4.0
2020-01-23T17:28:19.503Z
@dc37 No, my question is how to do a stacked bar graph with the error bars.
user6810
CC BY-SA 4.0
2020-01-23T17:28:49.657Z
@haci How do I change it to an interval?
user6810
CC BY-SA 4.0
2020-01-23T18:32:00.833Z
@user6810 Well, you have to have some min and max values to plot. Depends on why you need these error bars.
haci
CC BY-SA 4.0
2020-01-23T18:40:22.540Z
I want to indicate the error or uncertainty of each cell type.
user6810
<ggplot2>
stacked bargraph with error bars
# stacked bargraph with error bars

(Asked by: username_0 on 2020-01-23)

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))

**Tags:** ggplot2
> **Comments:**
> **username_1**: 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 https://bioinformatics.stackexchange.com/questions/11197/stacked-barplot-for-single-cell-analysis?  
> **username_0**: 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.  
> **username_1**: 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 ?  
> **username_0**: `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.  
> **username_1**: 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: https://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.  
> **username_2**: You are getting `Error: Cannot add ggproto objects together.` because you lack a `)` and `geom_text()` is not closed. And once this is fixed, you would get `Error: Discrete value supplied to continuous scale` because `geom_errorbar()` is for intervals but your `Condition` variable is a factor.  
> **username_0**: @dc37 No, my question is how to do a stacked bar graph with the error bars.  
> **username_0**: @haci How do I change it to an interval?  
> **username_2**: @user6810 Well, you have to have some min and max values to plot. Depends on why you need these error bars.  
> **username_0**: I want to indicate the error or uncertainty of each cell type.  

---

## 1 answers

### Answer by username_1 on 2020-01-23. Score: 1

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. 
Hope that it answers your question.

> **Comments:**
> **username_2**: For this scenario, I would advise against a barchart and would use a violin plot or a boxplot instead. The latter two would enable to assess the number of replicates within a group as well as the spread of the replicates.  
> **username_1**: 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`.  
> **username_2**: These numbers and graphs will not mean anything anyway if one does not have many replicates, especially if the data are from human samples and not from a model organism with a rather "clean" genetic background. Moreover, it is even more important to use box/violin plots when the number of replicates are small so that the reader is not mislead about the lack of power in the analyses. I guess, at least hope, that we will not see these plots in the future anyway: https://twitter.com/rafalab/status/1098973538260840449?lang=en  
> **username_1**: Totally agree ;) and personally, I won't publish those kind of results (at least in this format). But it's well beyond the scope of the question :D  
> **username_0**: These samples are derived from human samples, and I have replicates for each sample. A total of 32 samples, 16 from each condition. What do you all propose I should use to plot? I'm new at bioinformatics, and assumed a bargraph would be ideal. From reading the comments and answer, I don't have SD for each. I will add that.  
> **username_1**: If you have 16 for each conditions, you should associate them in a single dataframe and plot a boxplot or a violin plot as advised by @haci.  

---

