<p>(Following from comments)</p>
<p>I am 99% sure that, in the second code block, you are reordering only that one column and the rest of the columns are remaining unordered. That means that that column will be permuted with respect to the rest of the data, which I doubt is what you intend. I'd suggest instead running this, which will reorder the whole dataframe:</p>
<pre><code># not actually run cause I don't have the data, check it!
FY &lt;- FY[
         order(factor(FY$Suberin,
               levels = c(&quot;Con&quot;, &quot;Patchy&quot;,&quot;Non&quot; )
         ),
]
</code></pre>
<p>Consider this analogous example:</p>
<pre><code>&gt; test = data.frame(
  &quot;one&quot;=c(1,2,3), 
  &quot;two&quot;=c(6,5,4), 
  &quot;three&quot;=c(&quot;this&quot;, &quot;that&quot;, &quot;which&quot;)
)
&gt; test
  one two three
1   1   6  this
2   2   5  that
3   3   4 which
&gt; test<span class="math-container">$three = ordered(test$</span>three, levels=c(&quot;that&quot;, &quot;this&quot;, &quot;which&quot;))
# only column &quot;three&quot; is reordered!!!
&gt; test
  one two three
1   1   6  this
2   2   5  that
3   3   4 which

# THIS reorders the whole dataframe
&gt; test[order(test$three),]
  one two three
2   2   5  that
1   1   6  this
3   3   4 which

# impose a specific ordering by making it a factor, maybe there's a better way
&gt; test[order(factor(test$three, levels=c(&quot;that&quot;, &quot;which&quot;, &quot;this&quot;))),]
  one two three
2   2   5  that
3   3   4 which
1   1   6  this
</code></pre>
<p>I don't know that that impacts your error bar issue. But the underlying data will certainly be affected and possibly made inaccurate by permuting only one column.</p>
<p>Another thing that's a little weird is that you're computing <code>Mean_Percent</code> in two places: first, in your <code>summarise</code> expression, and then again when you actually make the plot with <code>geom_bar(stat=&quot;identity&quot;...</code>, which will fill the axes you've set up with newly estimated values based on the relative frequencies of the <code>Suberin</code> column. So you aren't plotting the <code>Mean_Percent</code> values that you are getting from <code>summarise</code>, as far as I can tell.</p>
<p>I'm a little scared of the way that you are computing mean/sd percentages and stacking them, especially not knowing what the data look like. I'd recommend confirming that your <code>Mean_Percent</code> that you compute with <code>summarise</code> adds up to 100%; for the actual bars in the barplot you are letting <code>geom_bar</code> recompute the proportions directly from the data, so I don't think the fact that it apparently adds up to 100% in the plot is trustworthy. To summarize: it'd make sense to confirm that what's in your dataframe matches what's in the plot since they are separately computed.</p>
<p>I don't know exactly that either of these issues is leading to your error bars having the wrong central tendencies, but investigating a couple of these lines may lead you to discover something.</p>
<p>I'm not a <code>ggplot</code> person so I can't diagnose just by looking at your code, and obviously I don't have your data so I can't tinker with it. Someone with more experience there might be a good idea. However, there are some <a href="https://stackoverflow.com/questions/30872977/how-to-stack-error-bars-in-a-stacked-bar-plot-using-geom-errorbar">related questions on SO</a> that <a href="https://stackoverflow.com/questions/42329858/stacked-percentage-barplot-with-error-bars-in-ggplot2?rq=3">may be worth reading over</a>.</p>
<p>Note again that none other than Hadley Wickham <a href="https://github.com/tidyverse/ggplot2/issues/1079" rel="nofollow noreferrer">finds this kind of plot confusing</a>.</p>

CC BY-SA 4.0
2023-12-01T04:07:21.800Z
Cool answer, @user185980 please consider marking it as accepted. `ggplot` is a hassle and there's no-one here who'd really do this ... I know it, its just fiddly.
M__
CC BY-SA 4.0
2023-12-01T20:39:18.343Z
@M__ appreciate the callout, but I'm not sure that my answer really addresses their concern- I didn't solve the problem! I merely have worries about the approach.
Maximilian Press
CC BY-SA 4.0
2023-11-29T19:57:31.253Z
2023-11-29T19:57:31.253Z
Maximilian Press
<p>I need to create a barplot with error bars, my data consists of 2 groups called &quot;Genot&quot;, with 3 sub-groups &quot;Suberin&quot; for each, associated with a value &quot;Percent&quot;.</p>
<pre class="lang-r prettyprint-override"><code>summary_data &lt;- FY %&gt;%
  group_by(Genot, Suberin) %&gt;%
  summarise(
    Mean_Percent = mean(Percent),
    SD_Percent = sd(Percent))


# plot
ggplot(summary_data, aes(x = Genot, y = Mean_Percent, fill=Suberin)) +
  geom_bar(stat = 'identity', aes(fill = Suberin)) +
  geom_errorbar(data = summary_data,
                aes(x = Genot, ymax = Mean_Percent + SD_Percent, ymin = Mean_Percent - SD_Percent), 
                , position = &quot;identity&quot;,width = 0.2)
</code></pre>
<p><a href="https://i.sstatic.net/qBK8J.png" rel="nofollow noreferrer"><img src="https://i.sstatic.net/qBK8J.png" alt="enter image description here" /></a></p>
<p>My main problem is that the error bars are placed from 0, but I have to order my data as the following to get the graph in the order I want.</p>
<pre class="lang-r prettyprint-override"><code>FY$Suberin &lt;- ordered(FY$Suberin,
                    levels = c(&quot;Con&quot;, &quot;Patchy&quot;,&quot;Non&quot; ))
</code></pre>
<p>I can't figure out a way to describe the positions</p>

CC BY-SA 4.0
2023-11-27T14:20:13.117Z
I understand why you're trying to do this, but I think that the plot will be kind of hard to look at regardless. I'd suggest making your life simpler and using grouped bars instead.
Maximilian Press
CC BY-SA 4.0
2023-11-27T14:22:59.140Z
wait, in your second code block, you are overwriting only that column. You're not actually reordering the rest of the data. Is that intentional?
Maximilian Press
CC BY-SA 4.0
2023-11-29T08:22:58.460Z
In my field and for these particular data stacked barplots are what we have to use
user18598
CC BY-SA 4.0
2023-11-29T08:29:07.207Z
In the second code block, I am reordering the full dataset based on the argument "Suberin", this is to obtain my plot with "Non", "Patchy" and "Con" (starting from 0)
user18598
<r><ggplot2>
stacked barplot with error bars
# stacked barplot with error bars

(Asked by: username_0 on 2023-11-22)

I need to create a barplot with error bars, my data consists of 2 groups called "Genot", with 3 sub-groups "Suberin" for each, associated with a value "Percent".
summary_data <- FY %>%
  group_by(Genot, Suberin) %>%
  summarise(
    Mean_Percent = mean(Percent),
    SD_Percent = sd(Percent))


# plot
ggplot(summary_data, aes(x = Genot, y = Mean_Percent, fill=Suberin)) +
  geom_bar(stat = 'identity', aes(fill = Suberin)) +
  geom_errorbar(data = summary_data,
                aes(x = Genot, ymax = Mean_Percent + SD_Percent, ymin = Mean_Percent - SD_Percent), 
                , position = "identity",width = 0.2)


My main problem is that the error bars are placed from 0, but I have to order my data as the following to get the graph in the order I want.
FY$Suberin <- ordered(FY$Suberin,
                    levels = c("Con", "Patchy","Non" ))

I can't figure out a way to describe the positions

**Tags:** r, ggplot2
> **Comments:**
> **username_1**: I understand why you're trying to do this, but I think that the plot will be kind of hard to look at regardless. I'd suggest making your life simpler and using grouped bars instead.  
> **username_1**: wait, in your second code block, you are overwriting only that column. You're not actually reordering the rest of the data. Is that intentional?  
> **username_0**: In my field and for these particular data stacked barplots are what we have to use  
> **username_0**: In the second code block, I am reordering the full dataset based on the argument "Suberin", this is to obtain my plot with "Non", "Patchy" and "Con" (starting from 0)  

---

## 1 answers

### Answer by username_1 on 2023-11-29. Score: 1

(Following from comments)
I am 99% sure that, in the second code block, you are reordering only that one column and the rest of the columns are remaining unordered. That means that that column will be permuted with respect to the rest of the data, which I doubt is what you intend. I'd suggest instead running this, which will reorder the whole dataframe:
# not actually run cause I don't have the data, check it!
FY <- FY[
         order(factor(FY$Suberin,
               levels = c("Con", "Patchy","Non" )
         ),
]

Consider this analogous example:
> test = data.frame(
  "one"=c(1,2,3), 
  "two"=c(6,5,4), 
  "three"=c("this", "that", "which")
)
> test
  one two three
1   1   6  this
2   2   5  that
3   3   4 which
> test$three = ordered(test$three, levels=c("that", "this", "which"))
# only column "three" is reordered!!!
> test
  one two three
1   1   6  this
2   2   5  that
3   3   4 which

# THIS reorders the whole dataframe
> test[order(test$three),]
  one two three
2   2   5  that
1   1   6  this
3   3   4 which

# impose a specific ordering by making it a factor, maybe there's a better way
> test[order(factor(test$three, levels=c("that", "which", "this"))),]
  one two three
2   2   5  that
3   3   4 which
1   1   6  this

I don't know that that impacts your error bar issue. But the underlying data will certainly be affected and possibly made inaccurate by permuting only one column.
Another thing that's a little weird is that you're computing Mean_Percent in two places: first, in your summarise expression, and then again when you actually make the plot with geom_bar(stat="identity"..., which will fill the axes you've set up with newly estimated values based on the relative frequencies of the Suberin column. So you aren't plotting the Mean_Percent values that you are getting from summarise, as far as I can tell.
I'm a little scared of the way that you are computing mean/sd percentages and stacking them, especially not knowing what the data look like. I'd recommend confirming that your Mean_Percent that you compute with summarise adds up to 100%; for the actual bars in the barplot you are letting geom_bar recompute the proportions directly from the data, so I don't think the fact that it apparently adds up to 100% in the plot is trustworthy. To summarize: it'd make sense to confirm that what's in your dataframe matches what's in the plot since they are separately computed.
I don't know exactly that either of these issues is leading to your error bars having the wrong central tendencies, but investigating a couple of these lines may lead you to discover something.
I'm not a ggplot person so I can't diagnose just by looking at your code, and obviously I don't have your data so I can't tinker with it. Someone with more experience there might be a good idea. However, there are some related questions on SO that may be worth reading over.
Note again that none other than Hadley Wickham finds this kind of plot confusing.

> **Comments:**
> **username_2**: Cool answer, @user185980 please consider marking it as accepted. `ggplot` is a hassle and there's no-one here who'd really do this ... I know it, its just fiddly.  
> **username_1**: @M__ appreciate the callout, but I'm not sure that my answer really addresses their concern- I didn't solve the problem! I merely have worries about the approach.  

---

