5

I am trying to create a grid of plots, which should have a box around them, a chessboard-like labelling (i.e., letters at top/bottom, numbers at the sides), as well as a vertical line separating two halfs of the grid.

I was hoping to get it done (or something similar enough) using faceting, but facet_grid does not create sideways labels (like here) when given a large number of plots, it appears:

testdata <- cbind("ID"=c(rep(1:24, each=10)), 
                  "TT"=c(rep(0:1, each=5)), 
                  "RD"=c(seq(1:5)), 
                  "DV"=rnorm(240, 10, 5))
testdata <- data.frame(testdata)

testplot <- ggplot(data=testdata, aes(x=RD, y=DV)) + 
  geom_line(colour="black") + geom_point() +
  facet_wrap(TT ~ ID, ncol=4)

enter image description here

(The other problem with facet_wrap is that it does not deal well with the ID ~ TT ordering I'd prefer, displaying these values as [1,0], [1,1], [2,0], [2,1] then; rather than the preferable [1,0], [2,0], [3,0], [1,1], [2,1]... but that could be worked around.)

Another option I've considered is using box(); however, this only works around individual plots (creating an object with grid.arrange / arrangeGrob does not work).

Ultimately, I'd like a plot roughly as below. I'd be happy about any suggestions!

Example

simoncolumbus
  • 526
  • 1
  • 8
  • 23
  • You can box off each graph by adding theme_bw(). I'm not certain exactly what you want. Do you want to use facet_wrap or facet_grid. I understand you want a vertical line down the middle but how should the final plot appear besides that line? Also where are you getting the letters you want to use from? Shouldn't you have a column in your data frame containing them? – Docconcoct Nov 09 '14 at 01:45
  • I reread and see you want the last graph as your output. The easiest way to proceed would be to add a column containing the letters A-D you want to represent each column associated with relevant graphs. That way facet_grid will automate it for you with the labels 1-24(?) on the right of the graphs as your first example showed. – Docconcoct Nov 09 '14 at 02:05
  • +1 for a well explained problem and clear code. – Tyler Rinker Nov 09 '14 at 04:10

2 Answers2

5

This seems pretty close.

set.seed(1)   # for reproducible example
testdata <- data.frame(ID=rep(LETTERS[1:4], each=60), 
                       TT=rep(1:6, each=10), 
                       grp=rep(0:1,each=5),
                       RD=seq(1:5), 
                       DV=rnorm(240, 10, 5))
library(ggplot2)
library(gridExtra)
ggp <- ggplot(data=testdata, aes(x=RD, y=DV, group=grp)) + 
  geom_line(colour="black") + geom_point() +
  facet_grid(TT ~ ID)+
  theme(strip.background=element_rect(fill=NA),
        strip.text=element_text(color="red",face="bold",size=15),
        strip.text.y=element_text(angle=0))
grid.newpage()
grid.draw(arrangeGrob(ggp))
grid.rect(x=0.51,y=0.5,width=0.007,height=0.8,gp=gpar(col=NA,fill="red"))

I added a grp variable to your example because you seem to want two lines in each panel.

We can get most of the way there with facet_grid(...) in ggplot, plus theme(...) to make the labels boldface and red, and turn off the strip (facet label) background.

To add the vertical line, unfortunately, requires the use of grid.rect(...) in the gridExtra package. As you can problaby see, there is some tweaking of the location of the rectangle to get it right. You are likly to need to do that if you have more that four categories across the top.

AFAIK there is no easy way to put the vertical facet labels on the left.

As a sidebar, note that you do not need, e.g., c(rep(...)). rep(...) already returns a vector. Also, and this is important, it is a really bad idea to use data.frame(cbind(...)). Just data.frame(...) accomplishes the same thing, is much faster, and does not produce an intermediate matrix.

jlhoward
  • 58,004
  • 7
  • 97
  • 140
0

To make my comments clearer.

I'd recommend creating a data frame that looks like this:

ID  TT  RD  DV          ColumnLetter     RowNumber
1   0   1   12.4734172       A               1
1   0   2   7.1034136        B               2
1   0   3   3.0688039        C               3
1   0   4   -2.4502442       D               4

Then use

face_grid(RowNumber~ColumnLetter)

to format as you desire.

Docconcoct
  • 2,040
  • 4
  • 28
  • 52