2

I'm trying to make axis labels bold if they contain specific text. I'm trying to do this to a plot that's the output of a function that also manipulates the my data, so there's no longer a direct relationship between my input data and the order of the labels in the output. So adding theme(axis.text.y = element_text(face = ifelse(levels(df$category) == "xxx", "bold", "plain"))) doesn't work (it turns the wrong label bold).

As a concrete example, if I had just this box plot of petal length by iris species as an object, would it be possible add a layer that would turn "setosa" bold if I didn't know the order the species would appear in?

Update: a reproducible example:

library(tidyverse)
library(rlang)

test <- tribble(
    ~AreaName, ~Value,
    "London",   1,
    "New York", 5,
    "Paris",    3
)

compare_areas <- function(data, area, value) {

    area <- enquo(area)
    value <- enquo(value)

    newLevels <- data[order(data[[quo_text(value)]], decreasing = TRUE), ][[quo_text(area)]]

    print(newLevels)


    data[[quo_text(area)]] <- factor(data[[quo_text(area)]], levels = newLevels)
    print(data)
    p <- ggplot(data, aes_string(x = quo_text(area), 
                                             y = quo_text(value))) +
        coord_flip() +
        geom_col()

    return(p)
}


compare_areas(data = test,
              area = AreaName,
              value = Value)

Plot output. So I'd want to make Paris bold, for example, but I don't know how the levels will be ordered.

Oliver
  • 1,098
  • 1
  • 11
  • 16

2 Answers2

1

You have to use levels(). When you apply df$category == "xxx" you get as many bold, plain values as there are rows in df.

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

enter image description here

The same is with iris dataset:

length(ifelse(iris$Species == "setosa", "bold", "plain"))
[1] 150
length(ifelse(levels(iris$Species) == "setosa", "bold", "plain"))
[1] 3
pogibas
  • 27,303
  • 19
  • 84
  • 117
  • 1
    Yes sorry that was a mistake on my part, but using `levels()` still doesn't work because the function that returns the plot also reorders the levels. Perhaps the ideal situation would be that the function would be split into a data cleaning function and a plotting function, but there's not much I can do about that right now – Oliver Feb 02 '18 at 14:11
  • 1
    @Oliver then you should update your question with reproducible example: add function and data – pogibas Feb 02 '18 at 14:12
  • This solution did not work for me either. The wrong level was made bold. But I found a good solution here: https://stackoverflow.com/questions/39694490/highlighting-individual-axis-labels-in-bold-using-ggplot2 – madsR Jun 12 '21 at 10:44
0

I'm going to take a guess and assume that all you have available is the ggplot object itself, i.e. after doing this:

library(ggplot2)
g1 <- ggplot(iris, aes(Species, Petal.Length)) +
    geom_boxplot()

you only have g1. Since the data that are going to be used to render the plot are stored within g1, you can build on @Oliver's answer as follows:

g1 + theme(axis.text.x = element_text(face = 
    ifelse(levels(g1$data$Species) == "setosa", "bold", "plain")))
Ben Bolker
  • 211,554
  • 25
  • 370
  • 453