user8701090
user8701090

Reputation: 58

Facet title alignment using facet_wrap() in ggplot2?

I'm making a plot involving facets, and I am trying to fix the alignment of the facet/strip title. Right now it seems to left align to the panel, which places it over the gap between the base of the column and the axis tick. I'd ideally have it align it with the base of the graph, or completely left align and move the base of the column closer to the y-axis label. Reprex below.

library(tidyverse)

tibble(ToothGrowth) %>% 
  mutate(dose = as_factor(dose),
         supp = as_factor(supp)) %>% 
  group_by(supp, dose) %>% 
  summarise(x = median(len)) %>% 
  ggplot(aes(y = supp, x = x)) +
  geom_col(fill = "grey55") +
  facet_wrap(~dose, ncol = 1) +
  labs(title = "Growing Teeth are less interesting than Irises") +
  theme_minimal() +
  theme(strip.placement = "inside",
        strip.text = element_text(hjust = 0),
        strip.background = element_blank(),
        panel.background = element_rect(fill = "grey95",
                                        color = NA))

Created on 2020-05-25 by the reprex package (v0.3.0)

Upvotes: 2

Views: 8157

Answers (3)

Gabe
Gabe

Reputation: 69

A better option for this is to set hjust=0, margin=margin(l=0):

plot.data <- tibble(ToothGrowth) %>% 
    mutate(dose = forcats::as_factor(dose),
           supp = forcats::as_factor(supp)) %>% 
    group_by(supp, dose) %>% 
    summarise(x = median(len)) %>%
    ggplot(aes(y = supp, x = x)) +
    geom_col(fill = "grey55") +
    scale_x_continuous(expand = c(0, 0)) +
    facet_wrap(~dose, ncol = 1) +
    labs(title = "Growing Teeth are less interesting than Irises") +
    theme_minimal() +
    theme(strip.text.x = element_text(hjust = 0, margin=margin(l=0)),
          panel.background = element_rect(fill = "grey95",
                                          color = NA))

enter image description here

The reason is that hjust is a percentage of the plot area while the offset you are compensating for is the margin which is in absolute units (pts I think). Because of this, the hjust offset needed is specific to the plot width. If you drag the figure wider or narrower, the location of the strip text will 'move' with relation to the bars when using hjust while it will be consistent when using 'margin'.

Upvotes: 4

Ian Campbell
Ian Campbell

Reputation: 24878

Here's an alternative to @teunbrand using expand = c(0,0) and a bit of nudging with hjust = -0.01:

plot.data <- tibble(ToothGrowth) %>% 
  mutate(dose = as_factor(dose),
         supp = as_factor(supp)) %>% 
  group_by(supp, dose) %>% 
  summarise(x = median(len)) %>%
ggplot(aes(y = supp, x = x)) +
  geom_col(fill = "grey55") +
  scale_x_continuous(expand = c(0, 0)) +
  facet_wrap(~dose, ncol = 1) +
  labs(title = "Growing Teeth are less interesting than Irises") +
  theme_minimal() +
  theme(strip.text.x = element_text(hjust = -0.01),
        panel.background = element_rect(fill = "grey95",
                                        color = NA))

enter image description here

Upvotes: 0

teunbrand
teunbrand

Reputation: 38063

Is this what you are looking for?

Essentially we put the facet strips on the left of the panels, and setup the (undocumented) theme element strip.text.y.left.

I could image you'd also want to have the strip text beyond the y-axis title even, but I'm afraid that is not possible without delving into the grid/gtables of the graph.

library(tidyverse)

tibble(ToothGrowth) %>% 
  mutate(dose = as_factor(dose),
         supp = as_factor(supp)) %>% 
  group_by(supp, dose) %>% 
  summarise(x = median(len)) %>% 
  ggplot(aes(y = supp, x = x)) +
  geom_col(fill = "grey55") +
  facet_wrap(~dose, ncol = 1, strip.position = "left") +
  labs(title = "Growing Teeth are less interesting than Irises") +
  theme_minimal() +
  theme(strip.placement = "outside",
        strip.text.y.left = element_text(angle = 0, vjust = 1),
        strip.background = element_blank(),
        panel.background = element_rect(fill = "grey95",
                                        color = NA))

Created on 2020-05-25 by the reprex package (v0.3.0)

Upvotes: 1

Related Questions