I want to make a 2x4 array of plots that show distributions changing over time. The default ggplot
arrangement with facet_wrap
is that the top row has series 1&2, the second row has series 3&4, etc. I would like to change this so that the first column has series in order (1->2->3->4) and then the second column has the next 4 series. This way your eye can compare immediately adjacent distributions in time vertically (as I think they should be).

- 8,059
- 14
- 56
- 83
-
Change the levels of wrapping factor..see [this]( http://stackoverflow.com/questions/5490638/how-to-change-the-order-of-facet-labels-in-ggplot-custom-facet-wrap-labels) – agstudy Feb 22 '13 at 23:26
-
I realize I can do this, but when the levels are just time points, it's a little kludgy, don't you think? The levels would be something like (1,10,2,20,3,30,4,40,...) and so on. – Evan Zamir Feb 22 '13 at 23:29
-
2I dont get your point here. can you provide a reproducible example please. – agstudy Feb 22 '13 at 23:36
-
There's really not much to get. If you use facet_wrap(~time) the order of plots will by default to increase across the rows and then columns. I want to reverse that. AFAICT, the only way seems to be able to re-level time as a factor out-of-order. – Evan Zamir Feb 23 '13 at 00:00
-
You could make a dummy variable that is a factor in the reverse order of your time variable, and use that in your plot instead... as I type this I see Dwin has already provided this as an answer. – Brandon Bertelsen Feb 23 '13 at 00:04
-
1possible duplicate of [facet\_wrap fill by column](http://stackoverflow.com/questions/12888302/facet-wrap-fill-by-column) – Eike P. Sep 08 '15 at 21:37
2 Answers
Use the direction dir
parameter to facet_wrap()
. Default is horizontal, and this can be switched to vertical:
# Horizontally
ggplot(mtcars, aes(x=hp, y=mpg)) + geom_point() + facet_wrap(~ cyl, ncol=2)
# Vertically
ggplot(mtcars, aes(x=hp, y=mpg)) + geom_point() + facet_wrap(~ cyl, ncol=2, dir="v")

- 15,909
- 12
- 89
- 97
Looks like you need to do this with the ordering factor prior to the the facet_wrap call:
fac <- factor( fac, levels=as.character(c(1, 10, 2, 20, 3, 30, 4, 40) ) )
The default for as/table in facet_wrap
is TRUE which is going to put the lowest value ("1" in this case) at the upper left and the highest value ("40" in the example above) at the lower right corner. So:
pl + facet_wrap(~fac, ncol=2, nrow=4)
Your comments suggest you are working with numeric class variables. (Your comments still do not provide a working example and you seem to think this is our responsibility and not yours. Where does one acquire such notions of entitlement?) This should create a factor that might be "column major" ordered with either numeric of factor input:
> ss <- 1:8; factor(ss, levels=ss[matrix(ss, ncol=2, byrow=TRUE)])
[1] 1 2 3 4 5 6 7 8
Levels: 1 3 5 7 2 4 6 8
On the other hand I can think of situations where this might be the effective approach:
> ss <- 1:8; factor(ss, levels=ss[matrix(ss, nrow=2, byrow=TRUE)])
[1] 1 2 3 4 5 6 7 8
Levels: 1 5 2 6 3 7 4 8

- 258,963
- 21
- 364
- 487
-
Unfortunately, I think this is the only way to do it. I just don't like it, because it's not very elegant. Oh, well. Can't win 'em all. Thanks. – Evan Zamir Feb 23 '13 at 00:37
-
2Your work case must be different, since the default ordering of the example I offered is the same as I created. Best answers are always achieved by greatest amount of information in the question. – IRTFM Feb 23 '13 at 00:58
-
All the information that is needed I have given. facet_wrap(~time) where time = 1,2,3,4... This will plot across rows first and then columns by default. Are you saying you get something different than that where it plots down the columns first and then the rows? – Evan Zamir Feb 23 '13 at 01:36
-
I was thinking it might be interesting to show `unique(fac)`. There are options about whether to display top first or bottom first and then there are the ordering option that arise once we know the specifics of the levels. The "devil is in the details" of what those three dots actually are. – IRTFM Feb 23 '13 at 01:41
-
In this case, I'm selecting rows out of the data set like ggplot(data[(data$days == 1 | data$days == 2 | data$days == 3),]). – Evan Zamir Feb 23 '13 at 01:46
-
Need a specific example. That one clearly does not fit the case of a 2 x 4 arrangement. The ...like... approach to problem description just doesn't provide enough of a cognitive "handle". You seem to be expecting us to read your mind and make up an example that will work for you. – IRTFM Feb 23 '13 at 01:51
-
Do you really need me to type this? Just extend up until data$days == 8. – Evan Zamir Feb 23 '13 at 02:04
-
What I really needed was a working example with the features of the data object. – IRTFM Feb 23 '13 at 18:19