Lod
Lod

Reputation: 639

Facet_wrap: conditional formatting based on label_value?

For some of my charts I would like to change the formatting of the numbers on the x axis for each facet conditionally on the label of the facet e.g. based on the order of magnitude (e.g. k, M, B etc.).

In the example below with the mtcars data, I would like the facet with gear==3 to keep the original number, with gear==4 create a "k" format and with gear==5 an "M" format. So that the two latter would be expressed in thousands and millions respectively.

Is is possible to use the label_value from the labeller to apply conditionally a format/function?

library(tidyverse)

d<-mtcars%>%mutate(mpg2=ifelse(gear==5,mpg*1000000,mpg))

ggplot(d) +
      geom_point(aes(mpg2, cyl)) +
      facet_wrap(~ gear, scales = "free")+
      scale_x_continuous(name = NULL,  labels = function(l) {
          return(paste0(round(l / 1000, 1), "K"))
      })

Upvotes: 0

Views: 1055

Answers (1)

Jon Spring
Jon Spring

Reputation: 66415

If you're looking to allow the scale formatting to vary according the value, here's a way using dplyr::case_when. (I don't know how to show the same numbers differently based on the facet, though.)

Edit to show wider range in example:

d <- mtcars %>% mutate(mpg2 = mpg ^ gear / carb)


ggplot(d) +
  geom_point(aes(mpg2, cyl)) +
  facet_wrap(~ gear, scales = "free")+
  scale_x_continuous(name = NULL,  trans = "log2", labels = function(l) {
     scaled = case_when(l >= 1E6 ~ paste0(formatC(l/1E6, digits = 0, big.mark = ",", format = "f"), "M"),
                        l >= 1E3 ~ paste0(formatC(l/1E3, digits = 0, big.mark = ",", format = "f"), "K"),
                        TRUE     ~ paste0(l))
     return(scaled)
})

enter image description here

I think it works pretty well.

If you need specific control over the labeling by facet, you might consider either faking the facet axis text with geom_text(aes(label = your_preferred_label)) and turning clipping off in coord_ so you can put text outside the plot range, or (more simply) combining plots with patchwork or cowplot. I'm not aware of a way to make the labeller itself aware of facet info.

Upvotes: 2

Related Questions