简体   繁体   中英

How do I line up my error bars with my bars in ggplot?

I'm creating a bar chart with a pattern for a subset of the bars, and I want to add error bars.

在此处输入图像描述

However, I'm having trouble lining up the error bars with with the bar charts—I want to have them appear centered on each bar. How do I do this? Moreover, the legend currently does not clearly distinguish the striped and non-striped bars as corresponding to not treated and treated groups.

Finally, I'd like to create version of this plot which stacks adjacent bars (ie bars within each facet_grid)—any tips on how to do that would be much appreciated.

The code I'm using is:

library(ggplot2)
library(tidyverse)
library(ggpattern)

models = c("a", "b")
task = c("1","2")
ratios = c(0.3, 0.4)
standard_errors = c(0.02, 0.02)

ymax = ratios + standard_errors
ymin = ratios - standard_errors

colors = c("#F39B7FFF", "#8491B4FF")

df <- data.frame(task = task, ratios = ratios)
df <- df %>% mutate(filler = 1-ratios)
df <- df %>% gather(key = "obs", value = "ratios", -1)
df$upper <- df$ratios + c(standard_errors,standard_errors)
df$models <- c(models,models)
df$lower <- df$ratios - c(standard_errors,standard_errors)
df$col <- c(colors,colors)
df$group <- paste(df$task, df$models, sep="-")
df$treated <- "yes"
df[df$ratios<0.5,]$treated = "no"

p <- ggplot(df, aes(x = group, y = ratios, fill = col, ymin = lower, ymax = upper)) + 
  stat_summary(aes(pattern=treated),
               fun = "mean", position=position_dodge(), 
               geom = "bar_pattern", pattern_fill="black", colour="black") +
        geom_errorbar(aes(ymin = lower, ymax = upper), width = 0.2, position=position_dodge(0.9)) +
        scale_pattern_manual(values=c("none", "stripe"))+ #edited part
        facet_grid(.~task, 
             scales = "free_x", # Let the x axis vary across facets.
             space = "free_x",  # Let the width of facets vary and force all bars to have the same width.
             switch = "x") + guides(colour = guide_legend(nrow = 1)) +
      guides(fill = "none")
p

Here is an option

df %>%
    ggplot(aes(x = models, y = ratios)) +
    geom_col_pattern(
        aes(fill = col, pattern = treated), 
        pattern_fill = "black",
        colour = "black",
        pattern_key_scale_factor = 0.2,
        position = position_dodge()) + 
    geom_errorbar(
         aes(ymin = lower, ymax = upper, group = interaction(task, treated)), 
         width = 0.2,
         position = position_dodge(0.9)) +
    facet_grid(~ task, scales = "free_x") +
    scale_pattern_manual(values = c("none", "stripe")) + 
    scale_fill_identity()

在此处输入图像描述

A few comments:

  • I don't understand the point of creating group . IMO this is unnecessary. TBH, I also don't understand the point of models and task : if task = "1" then models = "a"; if task = "2" then models = "b"; so task and models are redundant as they encode the same thing (whether you call it "1"/"2" or "a"/"b").
  • The reason why you (originally) didn't see a pattern in the legend is because of the scale factor in the legend key. As per ?scale_col_pattern , you can adjust this with the pattern_key_scale_factor parameter. Here, I've chosen pattern_key_scale_factor = 0.2 but you may want to play with different values.
  • The reason why the error bars didn't align with the dodged bars was because geom_errorbar didn't know that there are different task - treated combinations. We can fix this by explicitly defining a group aesthetic given by the combination of task & treated values. The reason why you don't need this in geom_col_pattern is because you already allow for different treated values through the pattern aesthetic.
  • You want to use scale_fill_identity() if you already have actual colour values defined in the data.frame .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM