Search code examples
rggplot2facet-wrapfacet-gridannotate

Multiple titles/labels on y-axis in ggplot2


I have a data frame that looks like this:

variable <- c("Financial wealth", "Financial wealth", "Financial wealth", 
              "Financial wealth", "Financial wealth", "Financial wealth", 
              "Financial wealth", "Financial wealth", "Financial wealth", 
              "Education", "Education", "Education", 
              "Education", "Education", "Education")
category <- c("<100\r\n(n=467)", "<100\r\n(n=467)", "<100\r\n(n=467)", 
              "100k to 500k\r\n(n=261)", "100k to 500k\r\n(n=261)", "100k to 500k\r\n(n=261)", 
              ">500k\r\n(n=72)", ">500k\r\n(n=72)", ">500k\r\n(n=72)", 
              "No higher education\r\n(n=397)", "No higher education\r\n(n=397)", "No higher education\r\n(n=397)", 
              "Higher education\r\n(n=506)", "Higher education\r\n(n=506)", "Higher education\r\n(n=506)")
name <- c("pillar 3a saver", "potential pillar 3a saver", "pillar 3a non-saver", 
          "pillar 3a saver", "potential pillar 3a saver", "pillar 3a non-saver", 
          "pillar 3a saver", "potential pillar 3a saver", "pillar 3a non-saver", 
          "pillar 3a saver", "potential pillar 3a saver", "pillar 3a non-saver", 
          "pillar 3a saver", "potential pillar 3a saver", "pillar 3a non-saver")
value <- c(0.649, 0.206, 0.146,
           0.782, 0.0843, 0.134, 
           0.736, 0.111, 0.153, 
           0.688, 0.159, 0.154, 
           0.719, 0.150, 0.130)

df <- data.frame(variable, category, name, value)

I then created a plot using ggplot2 as follows:


## results without securities
myplot = ggplot(df, 
                aes(fill = forcats::fct_rev(name), 
                    x = value, 
                    y = category)) + 
  # adjust generic theme for specific requirements
  theme(axis.title.x=element_blank(),
        axis.title.y=element_blank(),
        panel.grid.major.x = element_blank(),
        panel.grid.minor.y = element_blank(), 
        panel.grid.major.y = element_line(linetype = "dotted",
                                          colour = "darkgrey",
                                          size = 0.5),
        strip.background = element_blank(), 
        strip.text.x = element_text(
          face = "bold"
        ), 
        panel.border = element_blank(), 
        axis.line = element_line()) +
  # add relevant content for the graph
  geom_bar(stat = "identity", position = position_fill(reverse = FALSE),
           width=0.5) + 
  # adjust for scales
  scale_x_continuous(labels = scales::percent, expand = expansion(mult = c(0, .1))) +
  geom_text(aes(x = value, y = category, 
                label = percent(ifelse(value < 0.05, NA, value), accuracy = 0.1)), 
            stat = 'identity', size = 3, position = position_fill(vjust = 0.5))

I now want to add variable as a title on the y-axis, so that i looks like this: enter image description here

I tried using facet_grid(~variable, switch = "y")but this gives me two plots and the title is on the top instead on the left.

Any suggestions would be appreciated!


Solution

  • You could do it using facet_grid(), with strip.placement = "outside" in theme()

    library(scales)
    library(ggplot2)
    
    ggplot(df, 
           aes(fill = forcats::fct_rev(name), 
               x = value, 
               y = category)) +
      
      # add relevant content for the graph
      geom_bar(stat = "identity", position = position_fill(reverse = FALSE),
               width=0.5) + 
      # adjust for scales
      scale_x_continuous(labels = scales::percent, expand = expansion(mult = c(0, .1))) +
      geom_text(aes(x = value, y = category, 
                    label = percent(ifelse(value < 0.05, NA, value), accuracy = 0.1)), 
                stat = 'identity', size = 3, position = position_fill(vjust = 0.5))+
      # adjust generic theme for specific requirements
      theme(axis.title.x=element_blank(),
            axis.title.y=element_blank(),
            panel.grid.major.x = element_blank(),
            panel.grid.minor.y = element_blank(), 
            panel.grid.major.y = element_line(linetype = "dotted",
                                              colour = "darkgrey",
                                              size = 0.5),
            strip.background = element_blank(), 
            strip.placement = "outside",
            strip.text.x = element_text(
              face = "bold"
            ), 
            panel.border = element_blank(), 
            axis.line = element_line()) +
      facet_grid(variable ~., switch = "y",
                 scales = "free_y",
                 space = "free_y")
    #> Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
    #> ℹ Please use the `linewidth` argument instead.
    #> This warning is displayed once every 8 hours.
    #> Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
    #> generated.
    

    Created on 2023-05-08 with reprex v2.0.2