14

My data looks something like this:

df1 <-
  structure(
    list(
      y = c(-0.19, 0.3,-0.05, 0.15,-0.05, 0.15),
      lb = c(-0.61,
             0.1,-0.19,-0.06,-0.19,-0.06),
      ub = c(0.22, 0.51, 0.09, 0.36,
             0.09, 0.36),
      x = structure(
        c(1L, 2L, 1L, 2L, 1L, 2L),
        .Label = c("X1",
                   "X2"),
        class = "factor"
      ),
      Group = c("A", "A", "B", "B", "C",
                "C")
    ),
    .Names = c("y", "lb", "ub", "x", "Group"),
    row.names = c(NA,-6L),
    class = "data.frame"
  )

I want to use ggplot2 to plotthe points x,y colored by group with error bars lb, ub. Because x is discrete, I want to jitter so the points and bars don't overlap. Right now, I can jitter the points but not the lines. Additionally, I would like to have the order of the point to be A,B,C

ggplot(data = df1, aes(x, y, color = Group)) + geom_point(size = 4, position = "jitter") +
  geom_errorbar(
    aes(ymin = lb, ymax = ub),
    width = 0.1,
    linetype = "dotted"
  ) +
  geom_hline(aes(yintercept = 0), linetype = "dashed") + theme_bw()

enter image description here

Ignacio
  • 7,646
  • 16
  • 60
  • 113

2 Answers2

20

You can use position_dodge to achieve both the desired order and the error bars being drawn at the location of the points

ggplot(data = df1, aes(x, y, color = Group)) +
    geom_point(size = 4, position=position_dodge(width=0.5)) +
    geom_errorbar(
        aes(ymin = lb, ymax = ub),
        width = 0.1,
        linetype = "dotted",
        position=position_dodge(width=0.5)) +
    geom_hline(aes(yintercept = 0), linetype = "dashed") + 
    theme_bw()

enter image description here

konvas
  • 14,126
  • 2
  • 40
  • 46
  • This is a good answer, but what if there are multiple points in each x-axis category? `position_width` places all the points in a vertical lines, so that then the error bars overlap within the categories. Is there a way to achieve further jittering within category, and still have the error bars lined up with the points? – EcologyTom Apr 09 '18 at 07:34
  • @EcologyTom you could just define a new factor which takes into account the number of points in each category? for example if you had 2 points in the category A your factor levels would be A1, A2, B, C.. I don't think there is a way to combine dodge and jitter the way you are describing – konvas Apr 16 '18 at 10:36
  • That seems like a good workaround. I did eventually find [this answer](https://stackoverflow.com/questions/44595920/align-points-and-error-bars-in-ggplot-when-using-jitterdodge?noredirect=1&lq=1) which offered a solution. But your suggestion would be more straightforward, especially if there are not too many points. Thanks! – EcologyTom Apr 16 '18 at 11:20
6

If you want jitter, I do like this:

ggplot(data = df1, aes(x, y, color = Group)) +
    geom_pointrange(aes(ymin = lb, ymax = ub), 
                    position=position_jitter(width=0.5), 
                    linetype='dotted') +
    theme_bw()

enter image description here

retrot
  • 311
  • 4
  • 10