8

I'd like to create a faceted plot with margins in ggplot2. However, I'd like the margin plot to have colours according to from which facet the particular point has been derived. It's probably best illustrated with an example:

library(ggplot2)

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point()
p + facet_grid(.~gear, margins = TRUE)

Within the margin plot labelled as "(all)", I want those dots that have "gear = 3" to be plotted with one colour, those with "gear = 4" with a second colour, and those with "gear = 5" with a third one.

This one doesn't do the job:

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(col=gear))
p + facet_grid(.~gear, margins = TRUE)

Is there a way to achieve what I want?

AnjaM
  • 2,941
  • 8
  • 39
  • 62

2 Answers2

3

How about creating a new variable as a reference and colour the points by that? Seems to work provided you don't mind the points in the first 3 facets being coloured too.

mtcars$ref <- as.factor(mtcars$gear)

p <- ggplot(mtcars, aes(mpg, wt)) + geom_point(aes(col=as.factor(gear)))
p + facet_grid(.~ref, margins = TRUE)

All points coloured by gear

EDIT: I have managed to get it to remove the colour key from the first 3 facets but not without playing around with the original data;

Duplicate the original data (so there are 2 of each record) then instead of using a margin plot to produce the "all" facet, using the redundant records instead.

library(ggplot2)

mtcars$ref <- (mtcars$gear)

# create the duplicate
dat <- do.call("rbind", replicate(2, mtcars, simplify = FALSE)) 

# give the duplicates a false value for "gear" so they can be plotted together 
#This value can then be used for faceting, grouping everything with "all".

dat$ref[1:32] <- "all" 


# where not in the "all" facet, change "gear" to one (so they are plotted with the same colour)
dat$gear[dat$ref != "all"] <- 1

# then plot using ref as the facet and gear to colour points.

p <- ggplot(dat, aes(mpg, wt)) + geom_point(aes(col=as.factor(gear)))
p + facet_grid(.~ref, margins = F)

Points only coloured by gear in final facet

I'm not sure that's the best way to go about it but perhaps someone with more expertise might be able to advise?

Adam Kimberley
  • 879
  • 5
  • 12
  • Ok, thanks, that's a really good and straightforward idea! The only drawback is that in that case I don't see a way to remove the colours from the non-margin plots. Do you actually have any idea why `col(gear)` (or `col=(as.factor(gear))`) doesn't work, but `col=ref` does? – AnjaM May 06 '13 at 13:49
  • 1
    Is the edit any better? Not the most elegant solution but hope it helps. I think its to do with defining both colour and faceting with the same variable, ggplot gives each facet its own colour. – Adam Kimberley May 06 '13 at 14:49
  • 1
    @AnjaM you could try adding `scale_color_manual(values=c("black", "red", "green", "blue"))`. `col=(as.factor(gear))` won't work but `col=as.factor(gear)` should – Carson May 06 '13 at 15:26
  • @Carson You're right, the brackets aren't needed, that was just a typing error. What I meant by my question was why `ggplot2` doesn't apply the distinction by colour to the margin plot, although the colours are applied to the facet plots and although it works perfectly with a new variable (`col=ref`)? – AnjaM May 07 '13 at 07:55
  • `ggplot2` does apply the distinction by color to the margin plot as long as your faceting and coloring by different variables (which is way this "hacked" example works). A simpler example is: `qplot(mpg, wt, color=factor(cyl), data=mtcars)+facet_grid(.~gear, margins=TRUE)`. I'm not sure if there is a good reason why `qplot(mpg, wt, color=factor(gear), data=mtcars)+facet_grid(.~gear, margins=TRUE)` colors according to the factor level `(all)`. You might be inclined to ask the ggplot2 google group. – Carson May 07 '13 at 17:29
1

Another option would be to create the faceted plots and margin plot separately and use the gridExtra library to combine them:

library(ggplot2)
library(gridExtra)
mtcars$ALL <- "all"
p <- ggplot(mtcars, aes(mpg, wt))
p1 <- p + geom_point() + facet_grid(.~gear)
p2 <- p + geom_point(aes(color=factor(gear))) + facet_grid(.~ALL)
grid.arrange(p1, p2, ncol=2)

enter image description here

Carson
  • 2,617
  • 1
  • 21
  • 24
  • Thanks, that's a good idea as well! I didn't know that it's so easy to arrange `ggplot2` plots! – AnjaM May 07 '13 at 07:57