controlling order of facet_grid/facet_wrap in ggplot2?
RGgplot2R Problem Overview
I am plotting things using facet_wrap
and facet_grid
in ggplot, like:
ggplot(iris) + geom_histogram(aes(iris$Petal.Width)) + facet_grid(Species ~ .)
Is it possible to control the order in which the Species
panels are ordered in the plot? Can this be done without changing the iris
dataframe or making a new one? The default here shows setosa, versicolor, virginica but I'd like a different order. thanks.
R Solutions
Solution 1 - R
I don't think I can really satisfy your "without making a new data frame" requirement, but you can create the new data frame on the fly:
ggplot(transform(iris,
Species=factor(Species,levels=c("virginica","setosa","versicolor")))) +
geom_histogram(aes(Petal.Width))+ facet_grid(Species~.)
or, in tidyverse idiom:
iris %>%
mutate(across(Species, factor, levels=c("virginica","setosa","versicolor"))) %>%
ggplot() +
geom_histogram(aes(Petal.Width))+
facet_grid(Species~.)
I agree it would be nice if there were another way to control this, but ggplot
is already a pretty powerful (and complicated) engine ...
Note that the order of (1) the rows in the data set is independent of the order of (2) the levels of the factor. #2 is what factor(...,levels=...)
changes, and what ggplot
looks at to determine the order of the facets. Doing #1 (sorting the rows of the data frame in a specified order) is an interesting challenge. I think I would actually achieve this by doing #2 first, and then using order()
or arrange()
to sort according to the numeric values of the factor:
neworder <- c("virginica","setosa","versicolor")
library(plyr) ## or dplyr (transform -> mutate)
iris2 <- arrange(transform(iris,
Species=factor(Species,levels=neworder)),Species)
I can't immediately see a quick way to do this without changing the order of the factor levels (you could do it and then reset the order of the factor levels accordingly).
In general, functions in R that depend on the order of levels of a categorical variable are based on factor level order, not the order of the rows in the dataset: the answer above applies more generally.