4

If one tries to programmatically set the font face for axis labels, one process works in the absence of facets but breaks when facets are present. For instance

library(tidyverse)
library(magrittr)

data("mtcars")

mtcars  %<>% 
  rownames_to_column %>% 
  mutate(
    rowname = rowname %>% 
      fct_reorder(mpg)
  )


p1 <- mtcars %>% 
  ggplot(
    aes(mpg, rowname)
  ) +
  geom_point() +
  theme(
    axis.text.y = element_text(
      face = c("plain", "bold") %>% 
        rep(c(30, 2))
      )
    )

p1

Returns

plain and bold labels

But if I add facets, this pattern of plain and bold y-axis labels is lost

p1 + 
  facet_grid(
    cyl ~ .,
    scales = "free_y",
    space = "free_y"
    ) 

no plain and bold labels

How can I embolden some labels in the presence of facet_grid?

tomw
  • 3,114
  • 4
  • 29
  • 51
  • 1
    Maybe related: [ggplot2: Coloring axis text on a faceted plot](https://stackoverflow.com/questions/45843759/ggplot2-coloring-axis-text-on-a-faceted-plot) – Henrik May 17 '18 at 15:10

2 Answers2

2

This is a bit of a workaround but you should have no problem implementing it in your case. I toyed around with it a bit and had better luck creating an actual fontface variable right in the dataset and using numerics, instead of c("plain", "bold").

library(tidyverse)
library(magrittr)

data("mtcars")

mtcars  %<>% 
  rownames_to_column %>% 
  mutate(
    rowname = rowname %>% 
      fct_reorder(mpg)
  )

mtcars$font_face <- rep(c(1,2,3,4))

p1 <- mtcars %>% 
  ggplot(aes(mpg, rowname)) +
  geom_point() + 
  theme(axis.text.y = element_text(face = mtcars$font_face)) +
  facet_grid(cyl ~ .,
             scales = "free_y",
             space = "free_y")


p1

enter image description here

As you can see, the positions of the four faces are italic=1, bold=2, plain=3, and bold.italic=4.

So to recreate the example as you've presented, you just need to generate a variable in the original data piping and assign it using whatever relevant method. To recreate your example explicitly I'd go with the following code but I assume you'll want to work up a dplyr solution that actually fits your use case.

mtcars$font_face <- ifelse(mtcars$rowname %in% c("Toyota Corolla", "Fiat 128"), 2, 3)

edit:

The final solution is currently not working (the ifelse line). It recognizes the else value and selecting among 1:4 successfully changes the effect applied to the labels, but it doesn't pick change the labels for the if values, despite the fact that the mtcars$font_face variable does take on those values.

I'm stuck at the moment because I can't figure out why it ran for me before but not on a fresh session. I'm still working on figuring it out myself but perhaps my start can help someone to get to the next step.

cparmstrong
  • 799
  • 6
  • 23
  • This actually doesn't work for me, or even for the example set out in the question, in that, if you tried to use the `ifelse` statement and then plotted with `facet_grid`, all the labels are italicized – tomw May 18 '18 at 15:17
  • 1
    You're right. I had it working originally, but I just retried on a fresh session and it can't recreate it. I'll keep playing with it. – cparmstrong May 21 '18 at 12:46
0

This question has a hacky answer that nonetheless seems to work well for your problem: ggplot2: Coloring axis text on a faceted plot.

To adapt this to your problem, we have to move the fake axis to the y-axis and tweak the settings to make it look good with your data's labels.

library(tidyverse)
library(magrittr)

data("mtcars")

mtcars  %<>% 
    rownames_to_column %>% 
    mutate(
        rowname = rowname %>% 
            fct_reorder(mpg),
        font_face = as.factor(if_else(rowname %in% c("Toyota Corolla", "Fiat 128"), 'bold', 'plain'))
    )

mtcars %>% 
    ggplot(aes(mpg, rowname)) +
    geom_point() + 
    facet_grid(cyl ~ .,
               scales = "free_y",
               space = "free_y") +
    # make space to accommodate the fake axis
    expand_limits(x = -5) +
    # create a strip of white background under the fake axis
    geom_rect(xmin = -20, xmax = 0, ymin = 0, ymax = nrow(mtcars) + 1, fill = "white") +
    # fake axis layer
    geom_text(aes(fontface = font_face, label = rowname), x = -.2, vjust = .5, hjust = 1, size = 3)  + 
    # hide the actual axis text / ticks
    theme(axis.text.y = element_blank(), axis.ticks.y = element_blank())

Plot with appropriate row labels shown in bold

divibisan
  • 11,659
  • 11
  • 40
  • 58