Paolo Marra-Biggs
Paolo Marra-Biggs

Reputation: 11

Aligning error bars with different numbers of bars per group in ggplot2 & Misaligned error bars

I am creating bar graph across different islands (x axis labels) with error bars, but not all the islands have the same number of data bars (orange and/or blue bar). I adjusted the width of the bars by using position_dodge2(width = 0.7, preserve = "single"), but then the error bars are off center. So I tried to use position_dodge2(width = 0.7, preserve = "single") under geom_errorbar but it didn't work.

I also would like the same size gap between the islands, regardless of having blue and/or orange data bars

Would love tips! Mahalo!

`Island_bar_MMA <- ggplot(summary_data_MMA, aes(x = Island, y = mean_clams, fill = MMA)) +
  geom_bar(stat = "identity", position = position_dodge2(width = 0.7, preserve = "single"), width = 0.7, color = "black") +
  geom_errorbar(aes(ymin = mean_clams - se_clams, ymax = mean_clams + se_clams), 
                width = 0.2, position = position_dodge2(width = 0.7, preserve = "single"), 
                data = summary_data_MMA, 
                stat = "identity") + 
  scale_fill_manual(values = color_palette, name = "Protection") +
  labs(x = "Island", y = "mean / ha") + 
  theme_minimal() + 
  theme(
    legend.position = "bottom",
    legend.text = element_text(size = 9, face = "bold", color = "black"),
    legend.title = element_text(size = 13, face = "bold", color = "black"),
    panel.background = element_rect(fill = "grey90"),
    panel.grid.major.x = element_blank(),
    panel.grid.minor.x = element_blank(),
    panel.grid.major.y = element_line(color = "black", size = 0.1),
    axis.title.x = element_text(margin = margin(t = 5), size = 13, face = "bold", color = "black"),
    axis.title.y = element_text(margin = margin(t = 5), size = 13, face = "bold", color = "black"),
    axis.text.x = element_text(size = 12, face = "bold", color = "black"),
    axis.text.y = element_text(size = 12, face = "bold", color = "black"),
    panel.border = element_rect(color = "black", fill = NA, size = 1)
  )`

Upvotes: 1

Views: 42

Answers (1)

stefan
stefan

Reputation: 125163

The solution is somewhat burried in the docs. First, note that the docs already mention that position_dodge2

works with bars and rectangles, but is particularly useful for arranging box plots, which can have variable widths.

from which I infer that it is not well suited for error bars. (;

Second, after some googling I stumbled over this GH issue from 2017 which is closely related to your issue and from which I learned that an example on the use of "dodge2" with geom_errorbar can be found in the docs for ?geom_errorbar, i.e. to align the bars with the error bars we have to use the padding= argument.

To this end use the same width= for the error bars as for the bars (as already pointed out by @zephryl in the comments), which will ensure the proper alignment, then use the padding argument to set the "width" of the error bars.

Using some fake random example data:

library(ggplot2)

set.seed(123)

summary_data_MMA <- expand.grid(
  Island = LETTERS[1:3],
  MMA = letters[1:2]
)

summary_data_MMA$mean_clams <- runif(6)
summary_data_MMA$se_clams <- runif(6)

summary_data_MMA <- summary_data_MMA[-5, ]

ggplot(summary_data_MMA, aes(x = Island, y = mean_clams, fill = MMA)) +
  geom_bar(
    stat = "identity",
    position = position_dodge2(preserve = "single"), width = 0.7,
    color = "black"
  ) +
  geom_errorbar(
    aes(ymin = mean_clams - se_clams, ymax = mean_clams + se_clams),
    position = position_dodge2(
      preserve = "single",
      padding = .6
    ),
    width = 0.7,
    data = summary_data_MMA,
    stat = "identity"
  ) +
  labs(x = "Island", y = "mean / ha")

enter image description here

Upvotes: 0

Related Questions