Working with legends

Stefan McKinnon Edwards sme@iysik.com

2017-04-27

Legend functions

Reposition legend onto plotting panel

ggplot2 by default places the legend in the margin of the entire plot. This is in many instances a nice solution. If this is not desired, theme(legend.position) can be used to place the legend in relative measures on the entire plot:

library(ggplot2)
dsamp <- diamonds[sample(nrow(diamonds), 1000), ]
(d <- ggplot(dsamp, aes(carat, price)) +
  geom_point(aes(colour = clarity)) +
  theme(legend.position = c(0.1, 0.7))
)

This is however prone to badly positioning, if e.g. the plot is resized:

With our function, we can specify exactly how we want it in the plotting area:

library(splot)
reposition_legend(d, 'top left')

And it stays there.

reposition_legend(d, 'top left')

Facets

The above demonstration finds the panel named panel. This is default. If using facetting, the panels are typically named panel-{column}-{row}. Look at the column name in the following output.

d2 <- d + facet_grid(.~cut)
ggplot_gtable(ggplot_build(d2))
## TableGrob (11 x 15) "layout": 31 grobs
##     z         cells       name                                   grob
## 1   0 ( 1-11, 1-15) background        rect[plot.background..rect.556]
## 2   1 ( 7- 7, 4- 4)  panel-1-1               gTree[panel-1.gTree.369]
## 3   1 ( 7- 7, 6- 6)  panel-2-1               gTree[panel-2.gTree.384]
## 4   1 ( 7- 7, 8- 8)  panel-3-1               gTree[panel-3.gTree.399]
## 5   1 ( 7- 7,10-10)  panel-4-1               gTree[panel-4.gTree.414]
## 6   1 ( 7- 7,12-12)  panel-5-1               gTree[panel-5.gTree.429]
## 7   3 ( 5- 5, 4- 4)   axis-t-1                         zeroGrob[NULL]
## 8   3 ( 5- 5, 6- 6)   axis-t-2                         zeroGrob[NULL]
## 9   3 ( 5- 5, 8- 8)   axis-t-3                         zeroGrob[NULL]
## 10  3 ( 5- 5,10-10)   axis-t-4                         zeroGrob[NULL]
## 11  3 ( 5- 5,12-12)   axis-t-5                         zeroGrob[NULL]
## 12  3 ( 8- 8, 4- 4)   axis-b-1    absoluteGrob[GRID.absoluteGrob.436]
## 13  3 ( 8- 8, 6- 6)   axis-b-2    absoluteGrob[GRID.absoluteGrob.443]
## 14  3 ( 8- 8, 8- 8)   axis-b-3    absoluteGrob[GRID.absoluteGrob.450]
## 15  3 ( 8- 8,10-10)   axis-b-4    absoluteGrob[GRID.absoluteGrob.457]
## 16  3 ( 8- 8,12-12)   axis-b-5    absoluteGrob[GRID.absoluteGrob.464]
## 17  3 ( 7- 7, 3- 3)   axis-l-1    absoluteGrob[GRID.absoluteGrob.471]
## 18  3 ( 7- 7,13-13)   axis-r-1                         zeroGrob[NULL]
## 19  2 ( 6- 6, 4- 4)  strip-t-1                          gtable[strip]
## 20  2 ( 6- 6, 6- 6)  strip-t-2                          gtable[strip]
## 21  2 ( 6- 6, 8- 8)  strip-t-3                          gtable[strip]
## 22  2 ( 6- 6,10-10)  strip-t-4                          gtable[strip]
## 23  2 ( 6- 6,12-12)  strip-t-5                          gtable[strip]
## 24  4 ( 4- 4, 4-12)     xlab-t                         zeroGrob[NULL]
## 25  5 ( 9- 9, 4-12)     xlab-b titleGrob[axis.title.x..titleGrob.504]
## 26  6 ( 7- 7, 2- 2)     ylab-l titleGrob[axis.title.y..titleGrob.507]
## 27  7 ( 7- 7,14-14)     ylab-r                         zeroGrob[NULL]
## 28  8 ( 7- 7, 4-12)  guide-box                      gtable[guide-box]
## 29  9 ( 3- 3, 4-12)   subtitle  zeroGrob[plot.subtitle..zeroGrob.553]
## 30 10 ( 2- 2, 4-12)      title     zeroGrob[plot.title..zeroGrob.552]
## 31 11 (10-10, 4-12)    caption   zeroGrob[plot.caption..zeroGrob.554]

So to place the legend in a specific panel, give its name:

reposition_legend(d2, 'top left', panel = 'panel-3-1')

Likewise for facet_wrap. Incidentally, empty panels are also named here:

reposition_legend(d + facet_wrap(~cut, ncol=3), 'top left', panel='panel-3-2')

Modifying the legend is done via usual routines of ggplot2:

d3 <- d + facet_wrap(~cut, ncol=3) + scale_color_discrete(guide=guide_legend(ncol=3))
reposition_legend(d3, 'center', panel='panel-3-2')

Acknowledgements

g_legend can be found in few variations across a multitude of Stack Overflow answers.

grid_arrange_shared_legend was originally proposed by Shaun Jackman original code which was furhter refined by baptiste at ggplot2’s wiki.

reposition_legend was coded by Stefan McKinnon Edwards/