The purpose of a legend is to provide information about the data series to be found in the plot. The name of the data series or groups thus appears next to the symbol, color or any other feature used to represent them. In ggplot, a legend pops up automatically as soon as you use fill=, color=, size=, or shape= in aes() and describes how the function represents the corresponding variable.

It is possible to edit that legend in many ways, and we will see in this tutorial how to modify its title, position, colors, layout, and font. Here is the code for a reference plot stored in the object baseplot:

baseplot <- ggplot(df, aes(groups, values)) +
  geom_boxplot(aes(fill = groups))
baseplot



Some of the modifications to the legend that we will see in this tutorial will be achieved through modifications of the theme, meaning that we will write an extra line of code starting with theme().

Legend position

It is possible to change the position of the legend relative to the plot. By default, it is displayed to the right. Simply use legend.position= inside theme() to place it somewhere else. The options are "top", "bottom", "left" and "right". Note that there is a fifth option "none" that removes the legend from the plot. Here is an example with "bottom":

baseplot +
  theme(legend.position = "bottom")



If you need to place the legend anywhere else (including inside the plot area, legend.position= allows you to define the precise destination using coordinates. Instead of one of the five options described above, use c(x,y) where x and y define the position along the X- and Y-axis, respectively. The values must be in the range 0 to 1; this means that c(0,0) will put your legend in the lower left corner, while c(1,1) will put it in the top right corner. Note that precise placement will possibly require lots of trials and errors, until you reach the expected result.

baseplot +
  theme(legend.position = c(0.9, 0.2))



Legend layout

Depending on where you have placed the legend, or what the legend contains, you might want to have it displayed horizontally (alternatively vertically, if ggplot has displayed it horizontally due to other settings). This time, we will use legend.direction= with 2 possible options: "horizontal" and "vertical".

baseplot +
  theme(legend.position = c(0.365, 0.95), legend.direction = "horizontal")



ggplot usually displays either a column or a row with legend keys (the symbols/marks describing the data series). If you prefer to arrange these keys in 2-3 rows or columns, you may use the function guides() to rearrange the legend. Since the legend is brought by fill=, you must use the function guide_legend() after fill=. Finally, you may indicate the number of columns with ncol=.

baseplot +
  guides(fill= guide_legend(ncol = 2))



The option byrow= allows you to modify the order of the keys displayed in the legend. When set to TRUE, ggplot will first fill a row with A and B, then start the next row with C and D, and so on.

baseplot +
  guides(fill= guide_legend(ncol = 2, byrow = TRUE))



Legend title

The title of the legend may be modified directly via the function labs() which can be used also to modify the axis titles and plot title. Since the legend of the present plot is brought by the argument fill= in aes(), fill= must be used also in labs() to edit the legend title:

baseplot +
  labs(fill="New Title")



Alternatively, the legend title may be removed via element_blank() in the theme settings:

baseplot +
  theme(legend.title = element_blank())



Now, the look of the title may be modified via element_text(). Options like size=, face= and color= will help you tune it the way you want:

baseplot +
  theme(legend.title = element_text(face = "bold", color ="red", size=11))

Background color and frame

Finally, you may tune the background color of the whole legend area, as well as its frame. This can be done via the argument legend.background= and the specific function element_rect() which controls the box defining the area of the legend. The color and size of the frame are editable via color= and size=, while the background of the box is editable via fill=:

baseplot +
  theme(legend.background = element_rect(fill = "lightblue", color = "red", size = 2))