Hallie Sheikh
Hallie Sheikh

Reputation: 431

Errorbars and bar plots having different positions in ggplot

I have a dataframe df

> df
   id zone      mean   SE
1   1    1 0.9378712 0.10
2   1    2 2.4830645 0.09
3   1    3 0.7191759 0.09
4   1    4 1.3030844 0.09
5   1    5 1.2497096 0.11
6   1    6 0.7247015 0.15
7   1    7 0.1776825 0.16
8   1    8 1.4755258 0.13
9   1    9 1.0902742 0.16
10  1   10 0.2679057 0.08
11  1   12 0.7677998 0.09
12  2    1 1.2728942 0.14
13  2    2 1.3189574 0.07
14  2    3 1.0934750 0.14
15  2    4 1.3024298 0.10
16  2    5 1.3029797 0.11
17  2    6 1.0878356 0.12
18  2    7 0.5390098 0.12
19  2    8 1.2761170 0.09
20  2    9 1.1395524 0.12
21  2   10 0.6863418 0.14
22  2   12 1.1534048 0.12
23  3    1 1.2963668 0.14
24  3    2 1.3032349 0.07
25  3    3 1.1302980 0.14
26  3    4 1.3049038 0.10
27  3    5 1.3221782 0.11
28  3    6 1.0464710 0.14
29  3    7 0.4997006 0.13
30  3    8 1.2777002 0.09
31  3    9 1.1480874 0.12
32  3   10 0.6844529 0.15
33  3   12 1.1593346 0.13
34  4    1 1.2819611 0.14
35  4    2 1.4276992 0.07
36  4    3 1.1061886 0.14
37  4    4 1.3572913 0.11
38  4    5 1.3588146 0.12
39  4    6 1.1318426 0.14
40  4    7 0.5321167 0.12
41  4    8 1.3701237 0.10
42  4    9 1.1996266 0.13
43  4   10 0.6977050 0.14
44  4   12 1.2620727 0.14

Now it can be seen in zones that there is no 11 number, after 10 it comes 12. So when I plot it automatically it comes like this

axis_labels <- c("first","second","third","fourth","fifth","sixth","seventh","eigth","ninth","tenth","eleventh")
axis_labels <- setNames(axis_labels, 1:11)



ggplot(df, aes(x=factor(zone), y=mean, fill = id)) + 
  geom_col(position = position_dodge()) +
  scale_fill_discrete(labels = c("1" = "M", "2" = "I","3" = "Mi","4"="C"))+
  scale_x_discrete(labels = axis_labels) +
  theme(axis.title.x = element_blank(), 
        axis.line.x = element_blank(), 
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank()) +
  theme(plot.margin = unit(rep(0, 5), "pt"))+
  geom_errorbar(aes(x=zone, ymin=mean-SE, ymax=mean+SE), width=0.4, position = position_dodge(.9))+
  theme_bw()

So the bars at eleventh that are read are actually the twelveth zone in the dataframe but the errorbars are in the actual twelfth place. How can solve this problem without changing the whole code?

Upvotes: 0

Views: 49

Answers (1)

r2evans
r2evans

Reputation: 160407

The problem comes down to a few things:

  1. Up front, I'll make inferences about column class: I'm fairly confident that id should be character, but I'm not certain about zone. I'll guess character for now.

  2. You use factor(zone) in one aesthetic and zone in another; either all of them should be factor, or none, otherwise you are confusing ggplot2 (and me).

  3. You have 12 in your zone but your labels say eleventh, not sure if that's a typo or something else.

I think the fixes are to make a "proper" factor variable.

df$zone <- as.character(df$zone) # just in case
axis_labels <- setNames(axis_labels, c(1:10,12)) # no 11s in your data, no 12s in your labels
df$zone2 <- factor(axis_labels[df$zone], levels = axis_labels)

ggplot(df, aes(x=zone2, y=mean, fill = id)) + 
  geom_col(position = position_dodge()) +
  scale_fill_discrete(labels = c("1" = "M", "2" = "I","3" = "Mi","4"="C"))+
  scale_x_discrete(labels = axis_labels) +
  theme(axis.title.x = element_blank(), 
        axis.line.x = element_blank(), 
        axis.text.x = element_blank(),
        axis.ticks.x = element_blank()) +
  theme(plot.margin = unit(rep(0, 5), "pt"))+
  geom_errorbar(aes(x=zone2, ymin=mean-SE, ymax=mean+SE), width=0.4, position = position_dodge(.9))+
  theme_bw()

corrected errorbars


Data:

df <- structure(list(id = c("1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4"), zone = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "12"), mean = c(0.9378712, 2.4830645, 0.7191759, 1.3030844, 1.2497096, 0.7247015, 0.1776825, 1.4755258, 1.0902742, 0.2679057, 0.7677998, 1.2728942, 1.3189574, 1.093475, 1.3024298, 1.3029797, 1.0878356, 0.5390098, 1.276117, 1.1395524, 0.6863418, 1.1534048, 1.2963668, 1.3032349, 1.130298, 1.3049038, 1.3221782, 1.046471, 0.4997006, 1.2777002, 1.1480874, 0.6844529, 1.1593346, 1.2819611, 1.4276992, 1.1061886, 1.3572913, 1.3588146, 1.1318426, 0.5321167, 1.3701237, 1.1996266, 0.697705, 1.2620727), SE = c(0.1, 0.09, 0.09, 0.09, 0.11, 0.15, 0.16, 0.13, 0.16, 0.08, 0.09, 0.14, 0.07, 0.14, 0.1, 0.11, 0.12, 0.12, 0.09, 0.12, 0.14, 0.12, 0.14, 0.07, 0.14, 0.1, 0.11, 0.14, 0.13, 0.09, 0.12, 0.15, 0.13, 0.14, 0.07, 0.14, 0.11, 0.12, 0.14, 0.12, 0.1, 0.13, 0.14, 0.14)), class = "data.frame", row.names = c("1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12", "13", "14", "15", "16", "17", "18", "19", "20", "21", "22", "23", "24", "25", "26", "27", "28", "29", "30", "31", "32", "33", "34", "35", "36", "37", "38", "39", "40", "41", "42", "43", "44"))

Upvotes: 2

Related Questions