6

First, a quick example to set the stage:

set.seed(123)
dat <- data.frame( 
  x=rep( c(1, 2, 4, 7), times=25 ), 
  y=rnorm(100), 
  gp=rep(1:2, each=50) 
)

p <- ggplot(dat, aes(x=factor(x), y=y))
p + geom_boxplot(aes(fill = factor(gp)))

I would like to produce a similar plot, except with control over the x position of each set of boxplots. My first guess was using a non-factor x aesthetic that controls the position along the x-axis of these box plots. However, once I try to do this it seems like geom_boxplot doesn't interpret the aesthetics as I would hope.

p + geom_boxplot( aes(x=x, y=y, fill=factor(gp)) )

In particular, geom_boxplot seems to collapse over all x values in some way when they're non-factors.

Is there a way to control the x position of boxplots with ggplot2? Either through specifying a distance between each level of a factor aesthetic, some more clever use of non-factor aesthetics, or otherwise?

Josh O'Brien
  • 159,210
  • 26
  • 366
  • 455
Kevin Ushey
  • 20,530
  • 5
  • 56
  • 88
  • For some reason your 2 plots are not displaying. I took a look in the editing panel but cannot see what should be changed. – IRTFM Jan 25 '13 at 19:15
  • I'm confused by this too -- if I copy and paste the links and open them manually, they work... – Kevin Ushey Jan 25 '13 at 19:16
  • I was able to see them using the links to the SO versions of them, too. Color me puzzled. – IRTFM Jan 25 '13 at 19:17

2 Answers2

5

You can use scale_x_discrete() to set positions (ticks) for the x axis.

p <- ggplot(dat, aes(x=factor(x), y=y))
p + geom_boxplot(aes(fill = factor(gp))) + 
    scale_x_discrete(limits=1:7)
Didzis Elferts
  • 95,661
  • 14
  • 264
  • 201
5

You can also do this with the group aesthetic. However, I'm not sure why you cannot just pass x to the group. This doesn't work:

ggplot() + 
  geom_boxplot(data=dat, aes(x=x, y=y, fill=factor(gp), group=x))

But this does:

ggplot() + 
  geom_boxplot(data=dat, aes(x=x, y=y, fill=factor(gp), group=paste(x, gp)))
Justin
  • 42,475
  • 9
  • 93
  • 111