Home > Back-end >  adding title labels inside faceted barplots
adding title labels inside faceted barplots

Time:02-02

I am creating a faceted barplots showing (each plot = different element, bars = region) and instead of having the title for each plot in the strip above I want to insert them in the actual plots. Each plot has a wildly different y-axis so I am struggling with how to define a consistent y position for the title label. My code so far: I am thinking of using geom_text to add the labels?


    p1 <- ggplot(data = data, aes(region, concentration, fill = region))   
      geom_bar(stat="summary", fun = mean)  
      facet_wrap(~element,scales="free_y") 
      ylab("Element Concentration")  
      theme(strip.background = element_rect(fill=NA, color=NA),
            panel.background = element_rect(fill=NA, color="gray60"),
            panel.grid.major = element_blank(),
            panel.grid.minor = element_blank(),
            panel.spacing.x=unit(0, "lines"),
            panel.spacing.y=unit(.3, "lines"),
            strip.text = element_blank(),
            axis.title.x=element_blank(),
            axis.text.x=element_blank(),
            axis.ticks.x=element_blank())  
      scale_x_discrete(expand = c(0, 0))   
      scale_y_continuous(expand = expansion(mult = c(0, 0.3)))

what I have

what I want

Additionally: if anyone is familiar with how to do the following for the y axis label that would be fantastic: My y lab needs to say: "Element Concentration μg element/g Ca" Really struggling with adding in the microgram portion of the axis title.

CodePudding user response:

One option would be the gggrid package which similar to ggplot2::annotation_custom allows to place grobs on a ggplot using relative coordinates (and therefore works fine with different data range) but unlike ggplot2::annotation_custom allows for placing different grobs on each facet. To this end

  1. write a custom function which takes two arguments (data and coords) and which creates the textGrobs

  2. use gggrid::grid_panel to add the grobs to each facet or panel where we map element on e.g. the label aesthetic.

Using some fake random data:

library(ggplot2)
library(gggrid)
#> Loading required package: grid
library(grid)

title_label <- function(data, coords) {
  textGrob(unique(data$label),
    x = unit(.5, "npc"),
    y = unit(1, "npc") - unit(2, "mm"),
    vjust = 1,
    gp = gpar(fontsize = 10)
  )
}

ggplot(data = data, aes(region, concentration, fill = region))  
  geom_bar(stat = "summary", fun = mean)  
  grid_panel(title_label, aes(label = element))  
  facet_wrap(~element, scales = "free_y")  
  ylab("Element Concentration")  
  theme(
    strip.background = element_rect(fill = NA, color = NA),
    panel.background = element_rect(fill = NA, color = "gray60"),
    panel.grid.major = element_blank(),
    panel.grid.minor = element_blank(),
    panel.spacing.x = unit(0, "lines"),
    panel.spacing.y = unit(.3, "lines"),
    strip.text = element_blank(),
    axis.title.x = element_blank(),
    axis.text.x = element_blank(),
    axis.ticks.x = element_blank()
  )  
  scale_x_discrete(expand = c(0, 0))  
  scale_y_continuous(expand = expansion(mult = c(0, 0.3)))

DATA

set.seed(123)

data <- data.frame(
  region = sample(LETTERS[1:5], 100, replace = TRUE),
  concentration = unlist(lapply(1:5, function(x) runif(20, 0, 2 * x))),
  element = paste("element", 1:5)
)
  •  Tags:  
  • Related