Defining text for the legend of boxplot in ggplot2

How can I display a1 (random), a2 (random 2), a3 (random 3) in the legend instead of displaying the boxplot symbole?

The plot is here

The code I'm working with is

library(ggplot2)
library(reshape2)

B <- 25
datainit <- data.frame(v1 = 1:B, a1 = randl, a2 = rand2, a3 =  rand3)
idinit <- rep(c('a1', 'a2', 'a3'), each = B)
dat.minit <- melt(datainit, id.vars=idinit, measure.vars=c('a1', 'a2', 'a3'))
position <- c('a1', 'a2', 'a3')

plegend <- ggplot(dat.minit, aes(x = idinit, y = value, fill =  idinit)) +
 geom_boxplot(fill='white',color="darkred", show.legend = TRUE, width = 0.4) +     
 stat_boxplot(geom = "errorbar", width = 0.5, color="darkred") +
 labs(x =   "methods", y = "values")  +
 scale_x_discrete(limits = position)  +
 scale_fill_discrete(name="some\nmethods", 
    labels=c('random', 'random 2', 'random 3'))

The data is like

  v1        a1        a2        a3
1   1 0.6715123 0.6851999 0.6858062
2   2 0.6123710 0.6330409 0.6317203

1 answer

  • answered 2017-11-15 07:39 Sandy Muspratt

    One option could be to use grid commands to dig into the structure of the legend, and replace the boxplot keys with a1, a2, a3.

    library(ggplot)
    library(grid)
    
    plegend <- ggplot(dat.minit, aes(x = idinit, y = value, fill =  idinit)) +
      geom_boxplot(fill='white',color="darkred", show.legend = TRUE, width = 0.4)      + 
      stat_boxplot(geom = "errorbar", width = 0.5, color="darkred") +
      labs(x =   "methods", y = "values")  +
      scale_x_discrete(limits = position)  +
      scale_fill_discrete(name="some\nmethods", 
        labels=c('random', 'random 2', 'random 3'))
    
    # Get the plot grob
    g = ggplotGrob(plegend )
    
    # Get the legend
    leg = g$grobs[[which(g$layout$name == "guide-box")]]
    
    # Get the positions of keys in the legend layout
    pos = grep("key-.-1-1", leg$grobs[[1]]$layout$name)
    
    # Get the labels
    label = c("a1", "a2", "a3")
    
    # Replace the keys with the labels
    for(i in seq_along(pos)) {
       leg$grobs[[1]]$grobs[[pos[i]]] = textGrob(label[i], gp = gpar(cex = .75))
       }
    
    # Put the legend back into the plot
    g$grobs[[which(g$layout$name == "guide-box")]] = leg
    
    # Draw it
    grid.newpage()
    grid.draw(g)