Search code examples
rggplot2axis-labels

Conditional change of axis.text font family and font size creates unwanted 'gap'


I need to change the family and size of a specific x-axis element of a barplot, based on a condition.

I can successfully modify face using:

library(ggplot2)
ggplot(iris, aes(Species, Petal.Length)) + 
  geom_boxplot() + 
  coord_flip() +
  theme(axis.text.y = element_text(face = ifelse(levels(iris$Species)=="setosa","bold","italic")))

As suggested by: https://stackoverflow.com/a/20609878/8534926

However, for some reason when I try to apply family and size an empty gap is created between the axis and names.

ggplot(iris, aes(Species, Petal.Length)) + 
  geom_boxplot() + coord_flip() + 
  theme(axis.text.y = element_text(family = ifelse(levels(iris$Species)=="setosa","sans","mono")))

or

ggplot(iris, aes(Species, Petal.Length)) + 
  geom_boxplot() + coord_flip() + 
  theme(axis.text.y = element_text(size = ifelse(levels(iris$Species)=="setosa", 10, 20)))

I try to edit it using margin, but overlays can occur when the names are modified (using shiny app, for example).

what is this gap? Can I delete it?


Solution

  • The problem is fixed in the upcoming ggplot2 3.3.0, but it now triggers a warning, because this approach of formatting axis text is not reliable and could stop working at any point in the future.

    library(ggplot2) # v 3.3.0 or higher
    
    # discouraged, triggers warning message
    ggplot(iris, aes(Species, Petal.Length)) + 
      geom_boxplot() + coord_flip() + 
      theme(
        axis.text.y = element_text(
          size = ifelse(levels(iris$Species)=="setosa", 10, 20)
        )
      )
    #> Warning: Vectorized input to `element_text()` is not officially supported.
    #> Results may be unexpected or may change in future versions of ggplot2.
    

    As an alternative, the ggtext package under development attempts to provide a principle approach to this problem, by encoding the formatting instructions into the text labels.

    library(ggtext) # remotes::install_github("clauswilke/ggtext")
    library(dplyr)
    #> 
    #> Attaching package: 'dplyr'
    #> The following objects are masked from 'package:stats':
    #> 
    #>     filter, lag
    #> The following objects are masked from 'package:base':
    #> 
    #>     intersect, setdiff, setequal, union
    library(glue)
    #> 
    #> Attaching package: 'glue'
    #> The following object is masked from 'package:dplyr':
    #> 
    #>     collapse
    
    iris %>%
      mutate(
        Species = ifelse(
          Species == "setosa",
          "<span style = 'font-size:10pt'>setosa</span>",
          glue("<span style = 'font-size:20pt'>{Species}</span>")
        )
      ) %>%
      ggplot(aes(Species, Petal.Length)) + 
      geom_boxplot() + coord_flip() + 
      theme(axis.text.y = element_markdown())
    

    Created on 2020-01-16 by the reprex package (v0.3.0)