Search code examples
rggplot2facetfacet-wrap

Adding titles to each facet in facet_wrap


I am curious if it is possible to put axis titles on each facet in a facet_wrap. I can get close but I can't get x and y to display properly. The code is currently displaying both x and y on the same axis. I know this isn't exactly how it is supposed to function, but I want to see if it can be done without going to something more complex (arranging separate plots with grob or something).

In short, I would like y_names and x_names to appear on their respective axes.

testdat<-data.frame(x_names=c("A","B","C"),x_vals=c(1,2,3),y_names=c("B","C","A"), y_vals=c(2,3,1))
ggplot(testdat, aes(x_vals, y_vals)) +
  geom_point(pch=21) +
  facet_wrap(y_names~x_names, 
             ncol=1,
             scales="free",
             strip.position="left",
             labeller=as_labeller(c(A= "Apple",
                                    B= "Bread",
                                    C= "Cantaloupe"))
  )+
  theme( strip.background = element_blank(),
         strip.placement = "outside",
         axis.title.x=element_blank(),
         axis.title.y=element_blank())

Solution

  • I'm not sure exactly what you mean - perhaps this?

    library(ggplot2)
    
    testdat <- data.frame(x_names = c("A","B","C"),
                          x_vals  = c(1, 2, 3),
                          y_names = c("B", "C", "A"), 
                          y_vals  = c(2, 3, 1))
    
    ggplot(testdat, aes(x_vals, y_vals)) +
      geom_point(pch = 21) +
      facet_grid(y_names ~ x_names, 
                 labeller = as_labeller(c(A = "Apple",
                                          B = "Bread",
                                          C = "Cantaloupe")),
                  switch = "both") +
      theme( strip.background = element_blank(),
             strip.placement  = "outside",
             axis.title.x     = element_blank(),
             axis.title.y     = element_blank())
    


    EDIT

    The OP seems to want to have three (possibly completely unrelated) plots for when the two faceting factors are completely correlated. This is equivalent to faceting on a single variable. However, we want a separate axis for each facet. There are probably several ways to achieve this directly in ggplot, but they are all quite convoluted and include adding custom annotations.

    I think in this case by far the easiest and most freedom-preserving way is to add plots together using gridExtra::grid.arrange, which doesn't require any hacking or grob manipulation. It's as easy as:

    p1 <- ggplot(filter(testdat, x_names == "A", y_names == "B"), aes(x_vals, y_vals)) + 
            geom_point() + labs(x = "Apple", y = "Banana")
    
    p2 <- ggplot(filter(testdat, x_names == "B", y_names == "C"), aes(x_vals, y_vals)) +
            geom_point() + labs(x = "Banana", y = "Cherry")
    
    p3 <- ggplot(filter(testdat, x_names == "C", y_names == "A"), aes(x_vals, y_vals)) +
            geom_point() + labs(x = "Cherry", y = "Apple")
    
    gridExtra::grid.arrange(p1 , p2, p3)
    

    enter image description here Created on 2020-07-22 by the reprex package (v0.3.0)