coord_flip() failing to flip geom_errorbar() on plot

I am attempting to flip a plot in order to have the categorical variables on the y-axis, but my error bars are not flipping. Hopefully the image below does a better job than I am of explaining the issue:

I have used this method before to successfully flip ggplots with error bars, so I am not sure why it is not working this time around. Here is the code used to generate this plot:


avg_emit_consume %>% 
  group_by(country, type) %>% 
  pivot_wider(names_from = type, values_from = value) %>% 
  mutate(ratio = emissions / consumption) %>% 
  drop_na(ratio) %>% 
  ungroup() %>% 
  lm(ratio ~ food_category, data = .) %>% 
  tidy(conf.int = TRUE) %>% 
  mutate(term = ifelse(term == "(Intercept)", "Beef", term),
         term = str_remove(term, "food_category"),
         estimate = ifelse(term != "Beef", 
                           estimate + estimate[term == "Beef"], estimate),
         conf.low = ifelse(term != "Beef", 
                           conf.low + estimate[term == "Beef"], conf.low),
         conf.high = ifelse(term != "Beef", 
                           conf.high + estimate[term == "Beef"], conf.high),
         term = term %>% 
           as_factor() %>% 
           fct_reorder(estimate)) %>% 
  ggplot(aes(term, estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high)) +
  coord_flip(expand = TRUE) +
  labs(title = "Emissions to Consumption Ratio for \nEach Food Category", 
       subtitle = "Kilograms of CO2 per Kilogram Consumed") +
  ylab("Kilograms of CO2 Emissions of per Kilogram Consumed") +
  xlab("Food Category") +
  theme_classic()

Does this code work for you?

DF <- data.frame(Label = LETTERS[1:5], Values = 1:5, 
                 ValHigh = 1:5 + 0.3, ValLow = 1:5 - 0.3)
ggplot(DF, aes(Label, Values)) + geom_point() +
  geom_errorbar(aes(ymin = ValLow, ymax = ValHigh), width = 0.2) +
  labs(title = "Emissions to Consumption Ratio for \nEach Food Category", 
         subtitle = "Kilograms of CO2 per Kilogram Consumed") +
  ylab("Kilograms of CO2 Emissions of per Kilogram Consumed") +
  xlab("Food Category") +
  coord_flip(expand = TRUE) + theme_classic()

Yes, the error bars flip with the plot.

Let's try to use the same data. Please take all of your code before the call to ggplot() and store the result in a variable and then use dput() to make a call that reproduces that result. Something like

tmp <- avg_emit_consume %>% 
  group_by(country, type) %>% 
  pivot_wider(names_from = type, values_from = value) %>% 
  mutate(ratio = emissions / consumption) %>% 
  drop_na(ratio) %>% 
  ungroup() %>% 
  lm(ratio ~ food_category, data = .) %>% 
  tidy(conf.int = TRUE) %>% 
  mutate(term = ifelse(term == "(Intercept)", "Beef", term),
         term = str_remove(term, "food_category"),
         estimate = ifelse(term != "Beef", 
                           estimate + estimate[term == "Beef"], estimate),
         conf.low = ifelse(term != "Beef", 
                           conf.low + estimate[term == "Beef"], conf.low),
         conf.high = ifelse(term != "Beef", 
                           conf.high + estimate[term == "Beef"], conf.high),
         term = term %>% 
           as_factor() %>% 
           fct_reorder(estimate))

dput(tmp)

Post the result of dput() here and we can see how the plot looks using the same data you are using.

structure(list(term = structure(c(10L, 3L, 7L, 11L, 6L, 8L, 9L,
4L, 5L, 2L, 1L), .Label = c("Wheat and Wheat Products", "Soybeans",
"Eggs", "Poultry", "Rice", "Milk - inc. cheese", "Fish", "Nuts inc. Peanut Butter",
"Pork", "Beef", "Lamb & Goat"), class = "factor"), estimate = c(30.8578395021078,
0.918839779635313, 1.59650962057033, 35.0172960831113, 1.42440472068569,
1.77017723354569, 3.55081812529241, 1.07411907826274, 1.27980560328984,
0.399834766499971, 0.190682246067038), std.error = c(0.00416447057937936,
0.00588945077346207, 0.00588945077346208, 0.00590085339938138,
0.00588945077346205, 0.00588945077346205, 0.00598522048023851,
0.00588945077346199, 0.00588945077346205, 0.00618210531318005,
0.00588945077346204), statistic = c(7409.78688981556, -5083.49604641879,
-4968.43101455051, 704.89068266627, -4997.65358665524, -4938.94310138927,
-4562.40859747363, -5057.13037929636, -5022.20581112538, -4926.80133912833,
-5207.13364210929), p.value = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0), conf.low = c(30.8496701660344, 0.90728659376472, 1.58495643469974,
35.0057205289993, 1.4128515348151, 1.7586240476751, 3.53907707042253,
1.06256589239214, 1.26825241741925, 0.387707487658183, 0.179129060196445
), conf.high = c(30.8660088381812, 0.930392965505906, 1.60806280644093,
35.0288716372233, 1.43595790655629, 1.78173041941628, 3.56255918016229,
1.08567226413333, 1.29135878916043, 0.41196204534176, 0.20223543193763
)), class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,
-11L))

I have simplified the code, removing the coord_flip(), and the problem remains. I cannot see why geom_errorbar is confused. There is an orientation argument available in geom_errorbar but if I set it to "y" I get the error "Error: Elements must equal the number of rows or 1". I will keep looking at this but I hope someone smarter than I am will come along.

library(ggplot2)
DF <- structure(list(term = structure(c(10L, 3L, 7L, 11L, 6L, 8L, 9L,
                                        4L, 5L, 2L, 1L), 
                                      .Label = c("Wheat and Wheat Products", "Soybeans",
                                                 "Eggs", "Poultry", "Rice", "Milk - inc. cheese", 
                                                 "Fish", "Nuts inc. Peanut Butter","Pork", 
                                                 "Beef", "Lamb & Goat"), class = "factor"), 
                     estimate = c(30.8578395021078,0.918839779635313, 1.59650962057033, 
                                  35.0172960831113, 1.42440472068569,1.77017723354569, 
                                  3.55081812529241, 1.07411907826274, 1.27980560328984,
                                  0.399834766499971, 0.190682246067038), 
                     std.error = c(0.00416447057937936,0.00588945077346207, 0.00588945077346208, 
                                   0.00590085339938138,0.00588945077346205, 0.00588945077346205, 
                                   0.00598522048023851,0.00588945077346199, 0.00588945077346205, 
                                   0.00618210531318005,0.00588945077346204), 
                     statistic = c(7409.78688981556, -5083.49604641879,-4968.43101455051, 
                                   704.89068266627, -4997.65358665524, -4938.94310138927,
                                   -4562.40859747363, -5057.13037929636, -5022.20581112538, 
                                   -4926.80133912833,-5207.13364210929), 
                     p.value = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0), 
                     conf.low = c(30.8496701660344, 0.90728659376472, 1.58495643469974,
                                  35.0057205289993, 1.4128515348151, 1.7586240476751, 
                                  3.53907707042253,1.06256589239214, 1.26825241741925, 
                                  0.387707487658183, 0.179129060196445), 
                     conf.high = c(30.8660088381812, 0.930392965505906, 1.60806280644093,
                                   35.0288716372233, 1.43595790655629, 1.78173041941628, 
                                   3.56255918016229,1.08567226413333, 1.29135878916043, 
                                   0.41196204534176, 0.20223543193763)), 
                class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,-11L))

ggplot(DF, aes(term, estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high))

Created on 2020-04-30 by the reprex package (v0.3.0)

OK, I had a good laugh. What we are seeing are the "width" features of the error bars. That is, in the unflipped version, we are seeing the horizontal lines drawn at the extremes of the error bar whiskers. The span of the error bars is so small that they are not visible. If I restrict the y axis to a much smaller range, the error bars become visible, sort of.

library(ggplot2)
DF <- structure(list(term = structure(c(10L, 3L, 7L, 11L, 6L, 8L, 9L,
                                        4L, 5L, 2L, 1L), 
                                      .Label = c("Wheat and Wheat Products", "Soybeans",
                                                 "Eggs", "Poultry", "Rice", "Milk - inc. cheese", 
                                                 "Fish", "Nuts inc. Peanut Butter","Pork", 
                                                 "Beef", "Lamb & Goat"), class = "factor"), 
                     estimate = c(30.8578395021078,0.918839779635313, 1.59650962057033, 
                                  35.0172960831113, 1.42440472068569,1.77017723354569, 
                                  3.55081812529241, 1.07411907826274, 1.27980560328984,
                                  0.399834766499971, 0.190682246067038), 
                     std.error = c(0.00416447057937936,0.00588945077346207, 0.00588945077346208, 
                                   0.00590085339938138,0.00588945077346205, 0.00588945077346205, 
                                   0.00598522048023851,0.00588945077346199, 0.00588945077346205, 
                                   0.00618210531318005,0.00588945077346204), 
                     statistic = c(7409.78688981556, -5083.49604641879,-4968.43101455051, 
                                   704.89068266627, -4997.65358665524, -4938.94310138927,
                                   -4562.40859747363, -5057.13037929636, -5022.20581112538, 
                                   -4926.80133912833,-5207.13364210929), 
                     p.value = c(0, 0, 0, 0, 0, 0, 0, 0, 0, 0,0), 
                     conf.low = c(30.8496701660344, 0.90728659376472, 1.58495643469974,
                                  35.0057205289993, 1.4128515348151, 1.7586240476751, 
                                  3.53907707042253,1.06256589239214, 1.26825241741925, 
                                  0.387707487658183, 0.179129060196445), 
                     conf.high = c(30.8660088381812, 0.930392965505906, 1.60806280644093,
                                   35.0288716372233, 1.43595790655629, 1.78173041941628, 
                                   3.56255918016229,1.08567226413333, 1.29135878916043, 
                                   0.41196204534176, 0.20223543193763)), 
                class = c("tbl_df", "tbl", "data.frame"), row.names = c(NA,-11L))


ggplot(DF[c(5:11),], aes(term, estimate)) +
  geom_point() +
  geom_errorbar(aes(ymin = conf.low, ymax = conf.high)) +
  coord_flip(expand = TRUE) +
  labs(title = "Emissions to Consumption Ratio for \nEach Food Category", 
       subtitle = "Kilograms of CO2 per Kilogram Consumed") +
  ylab("Kilograms of CO2 Emissions of per Kilogram Consumed") +
  xlab("Food Category") +
  theme_classic() + ylim(0,2)
#> Warning: Removed 1 rows containing missing values (geom_point).

Created on 2020-04-30 by the reprex package (v0.3.0)

Thanks for giving me a laugh too! It definitely would have taken me a much longer time to figure that out.

I appreciate it!

This topic was automatically closed 7 days after the last reply. New replies are no longer allowed.