16

I have two sets of points with error bars. I would like to offset the second so it's displayed slightly down from the first set, so that it doesn't obscure the original.

Here is a mock data set:

x=runif(4,-2,2)
y=c("A","B","C","D")
upper=x+2
lower=x-2
x_1=runif(4,-1,3)
upper_1=x_1+1
lower_1=x_1-2

Here is the code that I used to produce the plot:

qplot(x,y)+
  geom_point(size=6)+
  geom_errorbarh(aes(xmax=upper,xmin=lower),size=1)+
  geom_point(aes(x_1,y),size=6,pch=8,vjust=-1,col="grey40")+
  geom_errorbarh(aes(xmax=upper_1,xmin=lower_1),size=1,col="grey40")

And here is the plot:

scatterplot

I would like the grey asterisks and associated errors bars to be plotted a hair below the black circles and associated error bars. I would transform the data set, but the Y-axis is categorical variables.

1
  • Richie's answer is much better than my approach, so I deleted mine. Commented Jul 25, 2011 at 16:37

4 Answers 4

24

Using Richie's reorganization of your data, this is also possible purely within ggplot, without having to mess with the axis:

dodge <- position_dodge(width=0.5)  
p <- ggplot(dfr,aes(x=y,y=x,colour=type)) + 
        geom_point(aes(shape=type),position=dodge) +
        geom_errorbar(aes(ymax=upper,ymin=lower),position = dodge) + 
        scale_colour_manual(values = c('gray','black')) +
        scale_shape_manual(values = c(8,19)) +
        coord_flip() + 
        opts(legend.position="none")

which gives me this plot:

enter image description here

Note: Since version 0.9.2 opts has been replaced by theme:

+ theme(legend.position = "none")
Sign up to request clarification or add additional context in comments.

5 Comments

Sorry, not familiar with the the scale_shape_manual and coord_flip arguments, but qplot is kicking back an error: Non-numeric argument to binary operator
@jslefche - You're probably introducing an error in trying to translate this solution to qplot. Learn to use ggplot(), it will pay dividends.
Ahh, I see what you did there with coord_flip(). Very nice. Works great with ggplot(). Marked as answered.
I know this question is old, but I need a little more help. I would like to have one symbol be an open circle (pch=21) but not have the error bar show THROUGH the symbol. Haven't been able to get this with scale_fill_manual. Any thoughts?
I can't think of anything off the top of my head. I think this might make a good SO question on its own, though.
10

Reorganise your data into a data frame.

x = runif(4,-2,2)
x_1 = runif(4,-1,3)
dfr <- data.frame(
  x = c(x, x_1),
  y = rep(c("A","B","C","D"), 2),
  upper = c(x+2, x_1+1),
  lower = c(x-2, x_1-2),
  type = rep(c("alpha", "beta"), each = 4)
)

Add a column that is a numeric version of the factor y.

dfr$y_numeric <- with(dfr, 
  as.numeric(y) - ifelse(type == "alpha", 0, 0.1)
)

           x y    upper       lower  type y_numeric
1 0.16694617 A 2.166946 -1.83305383 alpha       1.0
2 1.95060734 B 3.950607 -0.04939266 alpha       2.0
3 1.85516860 C 3.855169 -0.14483140 alpha       3.0
4 0.08773196 D 2.087732 -1.91226804 alpha       4.0
5 0.74837995 A 1.748380 -1.25162005  beta       0.9
6 0.61489655 B 1.614897 -1.38510345  beta       1.9
7 2.31641418 C 3.316414  0.31641418  beta       2.9
8 2.62842027 D 3.628420  0.62842027  beta       3.9

Now your plotting code is simpler.

ggplot(dfr, aes(x, y_numeric, colour = type)) +
  geom_point(size = 6) +
  geom_errorbarh(aes(xmax = upper,xmin = lower), size = 1) +
  scale_colour_grey()

final image with staggered plots

Comments

4

In most recent ggplot2, you can set the desired dodge width to match the width of the error bar tails using position = position_dodge(width = #):

set.seed(45)
data <- data.frame(group = c(rep("Z", 4), rep("Y", 4)),
                   value = runif(8),
                   x = rep(c("a","b","c","d"),2))

data$ll <- data$value - abs(runif(8))
data$ul <- data$value + abs(runif(8))


ggplot(data = data, aes(x = x, y = value, color = group)) +
  geom_point(size = 2, position = position_dodge(width = 0.2)) + 
  geom_hline(yintercept = 1, linetype = "dotted") +
  geom_errorbar(aes(ymin = ll, ymax = ul), width = 0.2, position = "dodge")

enter image description here

Comments

1

Jared Lander has a fantastic script up on github that creates a new function, position_dodgev, for horizontal error bars.

It's here: https://github.com/jaredlander/coefplot/blob/master/R/position.r

And I found it through his original post, which has an older version that doesn't currently work with my install of ggplot2: http://www.jaredlander.com/2013/02/vertical-dodging-in-ggplot2/

You can use his function as you would position_dodge with geom_errorbar, e.g.,

... + geom_errorbarh(aes(xmin = LowInner, 
    xmax = HighInner), height = 0.5, lwd = 1, position = position_dodgev(height = 0.8))

This solution worked for me, as I'm faceting the plot and didn't want to mess around with creating a new column in the data.frame.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.