facet_grid() allows for creating a multi-faceted plot. In this plot, each of the panels displays the data matching the combination of 2 levels, one for each of two categorical predictor variables. This results often in a more readable figure than a larger, unique figure where all the data point overlap.

Let’s illustrate this with the following histogram of distribution.

The dataframe for drawing this histogram is described below. It contains 3000 entries described by one of 6 levels (A, B, C, D, E and F) in the categorical variable groups and by one of 3 levels (1, 2 and 3) in the categorical variable categories:

# predictor variables
groups <- c(rep("A", 500), rep("B", 500), rep("C", 500), rep("D", 500), rep("E", 500), rep("F", 500))
categories <- as.factor(floor(runif(3000, min=1, max=4)))
# response variable
values <- c(rnorm(500, mean=50, sd=10), rnorm(500, mean=30, sd=5), rnorm(500, mean=40, sd=10), rnorm(500, mean=60, sd=20), rnorm(500, mean=70, sd=10), rnorm(500, mean=55, sd=15))
#dataframe
df <- data.frame(groups, categories, values)



Here are 2 color-coded histograms of distribution, one showing the levels of groups (left plot) and the other one showing the levels of categories (right plot):

ggplot(df, aes(values, fill=groups)) +        # left plot, levels of groups
  geom_histogram(bins=50) +
  scale_fill_viridis_d() 
  
ggplot(df, aes(values, fill=categories)) +    # right plot, levels of categories
  geom_histogram(bins=50) +
  scale_fill_viridis_d()



Using facet_grid(), you can immediately get an overview over all the groups and categories in the form of a 6 x 3 matrix. you just need to indicate groups and categories between the parentheses, and separated by ~:

ggplot(df, aes(values)) +
  geom_histogram(bins=50) +
  facet_grid(categories~groups)



Note that the order of the elements between the parentheses in facet_grid() determines the order of the matrix:

ggplot(df, aes(values)) +
  geom_histogram(bins=50) +
  facet_grid(groups~categories)

If you are not interested in combinations of groups/categories, you may choose to display a matrix based only on one element. Here you may choose to display only the groups in rows. Use rows = vars() in the following way:

ggplot(df, aes(values)) +
  geom_histogram(bins=50) +
  scale_fill_viridis_d() +
  facet_grid(rows = vars(groups))



Same request, but this time displayed in columns with cols = vars():

ggplot(df, aes(values)) +
  geom_histogram(bins=50) +
  facet_grid(cols = vars(groups))



By default in facet_grid(), the scales of the X- and Y-axes are fixed. This means that all the mini-plots will have the same scales, making them easy to compare. You may override that setting with scales =. This argument has 4 options:

Here are two examples, with free_x to the left and free to the right:

ggplot(df, aes(values)) +    # left plot, free_x
  geom_histogram(bins=50) +
  facet_grid(categories~groups, scales = "free_x") 

ggplot(df, aes(values)) +    # right plot, free
  geom_histogram(bins=50) +
  facet_grid(categories~groups, scales = "free")