showing different units in each free_y of facet_grid

557 views Asked by At

I have plotted two facets one on top of the other with two different ys (a percentage and a cost) and the same x (Years). I took most of the ideas from this post and some variations of the same. I'd like to show the labels of the y axis as percentages for the rate and as £ for the costs, but I have been unable to change each y label format independently.

Below a reproducible example using facet_grid (I managed to create a similar thing with facet_wrap but I get stuck with the same problem).

I considered using grid.arrange() from the gridExtra package, but it seemed that would bring other issues with the legend.

library(plyr)
library(tidyr)
library(dplyr)
library(ggplot2)
library(scales)

set.seed(12345)

my_labels <- function(variable, value){
  names_li <- list("percentage", "cost in pounds")
  return(names_li[value])
}


df <- data.frame(
  rate = runif(10, 0, 1),
  cost = rnorm(10, 100, 40),
  years = seq(from = 2001, to = 2010)
)

df %>%
  gather(type_of_var,
         value,
         rate:cost) ->
  df2


df2 %>%
  ggplot(aes(x = years,
             y = value,
             ymin = 0,
             ymax = .1)) +
  facet_grid(type_of_var ~ .,
             scales = 'free_y',
             labeller = my_labels) +
  labs(x = "Year",
       y = "") +

  geom_point(subset = . (type_of_var == "rate")) +
  geom_line(subset = . (type_of_var == "rate"),
            colour = "grey") +
  ## the following two lines don't work
  # scale_y_continuous(subset = . (type_of_var == "rate"),
  #                   labels = percent) +

  geom_bar(subset = . (type_of_var == "cost"),
           stat = "identity") +

  theme_bw() +
  theme(strip.text.y = element_text(size = 15,
                                    colour = "black"),
        plot.title = element_text(lineheight = 0.8,
                                  face = "bold")) +
  scale_x_continuous(breaks = seq(2001, 2010, 1)) +
  labs(title = "free_y y axis labels")

Thanks

1

There are 1 answers

1
baptiste On BEST ANSWER

as a fragile workaround, you could use

label_fun <- function (x) {
  if(max(x, na.rm=TRUE) > 1) dollar(x) else percent(x)
}

(assuming you only deal with big money and small percentages)