wilkelab / ggtext

Improved text rendering support for ggplot2
https://wilkelab.org/ggtext/
GNU General Public License v2.0
651 stars 37 forks source link

Inconsistent application when using facet_grid #54

Closed barrel0luck closed 3 years ago

barrel0luck commented 3 years ago

The logic of using element_textbox within theme() seems to be different from that of element_text() which made me think there was a bug in the code for a long period of time. Specifically, when faceting data using facet_grid, and using strip.text = element_textbox() to format the facet text, the formatting gets applied only to the x strip instead of both x and y strips. With strip.text = element_text() the formatting gets applied to both x and y strips. However, with element_textbox() to be able to apply formatting to y strip, you need an additional line in theme(), i.e. strip.text.y = element_textbox(). This is a bit confusing, especially if you're used to the usual theme logic.

library(tidyverse)
library(ggtext)

# Generate the dataset ----------------------------------------------------

# Don't bother with the comments in this section (those are for me)
factors <- data.frame(factor_1 = c("<em>Factor 1_1</em>", "<em>Factor 1_2</em>", "<em>Factor 1_3</em>", "<em>Factor 1_4</em>"),
                      factor_2 = c("<em>Factor 2_1</em>", "<em>Factor 2_2</em>", "<em>Factor 1_3</em>", "<em>Factor 1_4</em>"),
                      factor_3 = c("<em>Factor 3_1</em>", "<em>Factor 3_2</em>", "<em>Factor 1_3</em>", "<em>Factor 1_4</em>"),
                      factor_4 = c("<em>Factor 4_1</em>", "<em>Factor 4_2</em>", "<em>Factor 1_3</em>", "<em>Factor 1_4</em>"))

dataset <-data.frame(x = NULL,
                     y = NULL,
                     colfacet_factor = NULL,
                     rowfacet_factor = NULL)
for (i in 1:ncol(factors)) {
  for (j in 1:nrow(factors)) {
    x_data <- 1:1000
    y_data <- rnorm(n=1000)
    temp <- data.frame(x = x_data,
                       y = y_data,
                       colfacet_factor = factors[i],
                       rowfacet_factor = factors[j]) # These names are not getting applied, I get colnames factor_1, and factor_1.1 instead. Thus need the next line.
    colnames(temp) <- c("x", "y", "colfacet_factor", "rowfacet_factor") # Not sure why I've to do this
    dataset <- rbind(dataset, temp)
  }
}

# Plotting with ggtext for labels -----------------------------------------
# Please read the comments in this section

# Shouldn't just setting strip.text = element_textbox() be sufficient for both x and y strips?
# Then further if you want some specific alteration in the x and y strip you can go for strip.text.x or strip.text.y
# But what is set for strip.text must get applied to both x and y strips.
# This however doesn't happen with element_textbox and the formatting is applied only to x strips.
# This behavior seems to be different from the usual logic of setting theme elements
ggplot(dataset, aes(x = x, y = y)) +
  facet_grid(colfacet_factor~rowfacet_factor) +
  geom_point() +
  theme(strip.text = element_textbox())

# Just to show when using element_text, the formatting gets applied to both x strips and y strips
ggplot(dataset, aes(x = x, y = y)) +
  facet_grid(colfacet_factor~rowfacet_factor) +
  geom_point() +
  theme(strip.text = element_text(size = 20))
# Thus the logic of element_textbox seems to be different from that of element_text

# So, when using element_textbox, to get formatting on the y strips as well I need to use this code:
ggplot(dataset, aes(x = x, y = y)) +
  facet_grid(colfacet_factor~rowfacet_factor) +
  geom_point() +
  theme(strip.text = element_textbox(),
        strip.text.y = element_textbox(orientation = "right-rotated"))
# Which is unnecessary going by the usual logic and so it took me a long time to figure this out.
# Also with element text the y strips by default have right-rotated orientation, but with element_textbox it needs to be set separately.
# I know this orientation part is complex, but maybe there's a solution for that
clauswilke commented 3 years ago

That's just how ggplot2 themes work. Nothing to do with ggtext in particular.

barrel0luck commented 3 years ago

So in your opinion when I code in strip.text = element_textbox() what should that get applied to? Just the x strips or both x and y strips?

clauswilke commented 3 years ago

Most themes explicitly set strip.text.y = element_text(...) so setting strip.text = element_textbox() won't override that setting. You'll have to set strip.text.y also.

barrel0luck commented 3 years ago

Ok. I guess I was just used to changing everything with one shot using strip.text = element_text(). Thanks anyway and I have to tell you it's really easy to format complex stuff with ggtext. After years of struggling with expression and bquote, finding ggtext is like finding an oasis in a desert. Thanks for developing this package. It's longer to write stuff for sure, but much more intuitive since I'm used to markdown language.