Home > Back-end >  X labels gets cut out for faceted ggplot in R
X labels gets cut out for faceted ggplot in R

Time:07-25

I formatted facet_wrap so that its lables will be on the at the plot bottom instead of on top of the plot (see pic attached). When the faceted label is too long, it get's cut out of the facet borders. How can I override this to allow longer strings to be in front of the facet graph?

In the attached plot the second facet label (which is 'really_really_really_long_lable_here') gets cut.

I can change figure dimensions and text size but the optimal solution for me is to arrange the facet strip text to be in front of the figure itself and therefore to allow long strings to appear in full length.

Dataframe to recreate this example:

df <- data.frame(a = c(seq(1:10)), b = seq(1:10), group = c(rep('group1',5), rep('really_really_really_long_lable_here',5)), 
                 sex = c(rep(c('M','F'),5)))


ggplot(df, aes(sex,b, group = sex))  
              geom_boxplot()  
              facet_wrap(~group, strip.position = "bottom")  
              theme(strip.placement = "outside",
                    strip.background = element_blank(),
                    text = element_text(size = 16))  
              xlab(NULL)

enter image description here

2. Change the font size:

p  
  theme(strip.text = element_text(size = 6))

enter image description here

3. Use text wrapping:

# Wrapping function that replaces underscores with spaces
wrap_text <- function(x, chars = 10) {
  x <- gsub("_", " ", x)
  stringr::str_wrap(x, chars)
}

# Alternative wrapping function that just drops a linebreak in every 10
# chars
wrap_text2 <- function(x, chars = 10) {
  regex <- sprintf("(.{%s})", chars)
  gsub(regex, "\\1\n", x)
}

p  
  facet_wrap(
    ~group, strip.position = "bottom",
    labeller = as_labeller(wrap_text)
  )

enter image description here

4. Use strip.clip

As of July 2022, the (unreleased) development version of ggplot2 includes a strip.clip argument to theme(). Setting this to "off" means the strip text will be layered on top of the panel like so:

p  
  theme(strip.clip = "off")

enter image description here

Note: you can get the development version of ggplot2 using remotes::install_github("tidyverse/ggplot2"). Or you can wait a few months for the next version to arrive on CRAN.

My favourite approach is #3 - or to just use shorter labels!

CodePudding user response:

You can use str_wrap from {stringr} package to handle long labels in plots.

library(ggplot2)
library(stringr)


df <- data.frame(a = c(seq(1:10)), b = seq(1:10), 
                 group = c(rep('group1',5), rep('really_really_really_long_lable_here',5)), 
                 sex = c(rep(c('M','F'),5)))


wrap_label <- function(x) str_wrap(str_replace_all(x, "_", " "), width = 20)

ggplot(df, aes(sex,b, group = sex))  
  geom_boxplot()  
  facet_wrap(~group, strip.position = "bottom", labeller = as_labeller(wrap_label))  
  theme(strip.placement = "outside",
        strip.background = element_blank(),
        text = element_text(size = 16))  
  xlab(NULL)

plot with multiline label for facet

  • Related