Dr. Mark Gardener

Home
About
 

Index of MonogRaphs

R: MonogRaphs

A series of essays on random topics using R: The Statistical Programming Language

R is a powerful and flexible beast. Getting started using R is not too difficult and you can learn to start using R in an afternoon. However, mastering R takes rather longer! These monographs are my way of exploring various topics in a completely unstructured manner.

Tips & Tricks for R | An Introduction to R| Writer's Bloc | Courses


I am legend

A legend is a tool to help explain a graph. You are most commonly going to want to add one to a bar chart where you have several data series. You'll also want to add one to a line or scatter plot when you have more than one series. Essentially you use a legend to help make a complicated plot more understandable.

In R you can add a legend to any plot using the legend() command. You can also use the legend = TRUE parameter in the barplot() command. The barplot() command is the only general plot type that has a legend parameter (the others need a separate legend).

The legend() command has a host of parameters, which can be tweaked to produce the finished article. Generally the most difficult part is making room on the chart for the legend itself!


Pelagic Publishing Logo

Contents


Essential R Reference Cover

The legend() command has a lot of possible parameters.

Specify parameters explicitly in plotting to make it easier to match them in the legend.

Top

Legend Essentials

The legend() command has a wealth of parameters at its disposal. This gives it a great deal of flexibility and customizability <sic> but this also makes it daunting and hard to get to grips with.

The legend() command has the following general form:

legend(x, y = NULL, legend, col, pch, lty, lwd, fill, border, bty, ncol, y.intersp)
x, y = NULL The co-ordinates to place the legend (its top-left corner). You can also specify a shortcut location as a text string: "top", "right", "bottomleft" and so on, which allows a general spot to be filled quickly.
legend The text to be used for the legen entries. The default is taken from the data.
col The colors to be used for lines or points that appear in the legend.
pch The plotting character(s) to use.
lty The line type (style) to use.
lwd The line width to use.
fill = NULL A set of colors to appear in boxes beside the legend text entries. If NULL (the default) an empty box is placed. To suppress the box omit the fill parameter.
border = "black" The border color for the box if fill is specified (as a color or NULL).
bty = "o" The border type for the overall legend, use bty = "n" for no border.
ncol = 1 The number of columns for the legend, the default is 1 (i.e. a vertical legend).
y.intersp = 1 The width between legend lines, set >1 to space the lines out. There is also a x.intersp parameter, which operates horizontally.

There are a number of other parameters that I've not listed. The ones here are the most essential.

When adding a legend you need to make sure that the items in the legend() command match the parameters you set in the plotting command. It helps to specify pch, col, lty and so on explicitly in the plotting command, as you can match the parameters more easily than if you relied on the defaults.

The barplot() command is the only general plotting command that has a legend parameter. You can pass additional parameters to the legend using the args.legend parameter, as you'll see shortly.


The barplot() command can make a legend with the legend parameter

Pass parameters
to legend() using
args.legend = list(...)

Sample Data:
butterfly.RData

Top

Adding legends from the barplot() command

The barplot() command allows use of a legend parameter, which calls legend() with its basic settings. You can pass parameters to the legend() command by adding args.legend and giving the details as a list().

The biggest problem is usually how to make appropriate space for the legend to fit in the plot window. There are two main options:

  • Alter the axis size to give extra room (vertically or horizontally).
  • Place the legend into the plot margin.

The following examples use a matrix dataset that gives the abundance of some butterfly species at a site over several sample years:

> bf
1996 1997 1998 1999 2000
M.bro 88 47 13 33 86
Or.tip 90 14 36 24 47
Paint.l 50 0 0 0 4
Pea 48 110 85 54 65
Red.ad 6 3 8 10 15
Ring 190 80 96 179 145
> class(bf) # Check you have a matrix
[1] "matrix"

You can get the sample data here: butterfly.RData.


Alter the y-axis using
ylim = c(start, end)
to make room for the legend in a barplot()

Top

Altering the y-axis to make room

In a basic plot there will often not be enough room to accommodate the legend:

> barplot(bf, legend = TRUE)

Not enough room for the legend
The default legend will often not fit.

Note that the default location for the legend is "topright". In this case the simplest way to make room is to resize the y-axis using the ylim parameter.

> barplot(bf, legend = TRUE, ylim = c(0,550))

More space on the y-axis for the legend
A simple rescale of the y-axis will often allow the legend to fit.

You may have to play around with the axis setting to get the best values to use.


Pass parameters
to legend() using
args.legend = list(...) in a barplot() command

Top

Pass legend parameters via barplot()

To pass parameters (arguments) to the legend() command from barplot() the parameters need to be passed as a list() with the args.legend parameter.

> barplot(bf, beside = TRUE, col = terrain.colors(6),
ylim = c(0, 250), legend = TRUE,
args.legend = list(bty = "n", x = "top", ncol = 3))
> title(xlab = "Sample Year", ylab = "Abundance")

Legend at the top
Parameters can be passed to legend() from barplot()

In this case the y-axis is lengthened and additional parameters passed to legend(). The legend box is suppressed (bty = "n"), placed at the top center (x = "top"), and made into 3 columns (ncol = 3).


Use the xlim = c(start, end) parameter to alter the x-axis and allow room for the legend on the right.

Allow 1 unit per bar and a bit extra to accommodate the legend.

Top

Altering the x-axis to make room

You can alter the x-axis using the xlim parameter, which allows you to place the legend at the right.

> mycols = c("tan", "orange1", "magenta", "cyan", "red", "sandybrown")
> barplot(bf, beside = TRUE, col = mycols, legend = TRUE, xlim = c(0, 45))

Legend placed on the right
Altering the x-axis gives room for the legend on the right.

Note that the xlim parameter in this example set the axis from 0 to 45. Each bar in the barplot() takes up a space, so you need to allow about 1 unit per bar plus a bit extra for the legend itself.

Note also that the col command set the colors for the plot, which were passed automatically to legend() without requiring the args.legend parameter. Of course if you wanted other parameters (such as supressing the legend box) you would require the args.legend parameter.


Place a legend() in the margin of any plot by altering graphical parameters via par()

Top

Place a legend in a plot margin

Altering the x-axis or y-axis size to accommodate the legend is a fairly simple matter. Sometimes however you want a legend to be at the bottom or even the left, and however you alter the axes you will not make space!

What you need is to be able to place the legend in the margin of the plot, so that it does not overlap the plotting zone at all. To do this you need to tweak the graphical parameters via the par() command.

The general running order is as follows:

  1. Set the plot margins as you need to give the space in the required margin.
  2. Make your plot (any plot).
  3. Reset the graphical parameters back to defaults.
  4. Now set the plot margins to 0 and at the same time set plotting to allow "overplot".
  5. Use legend() to place the legend where your extra large margin is.
  6. Reset the graphcal parameters back to defaults.

Steps 3 and 6 are not absolutely essential but preferrable, as you can get into an awful mess if you forget the current settings.


Use par(oma) to set plot margins to leave room for a legend.

Use par() with oma, mar, and new = TRUE to overplot a legend into the margin

Top

Legend in the plot margin for a bar chart

To make the plot margin larger use par(oma = c(b, l, t, r)) where b, l, t, r are values for the margin sizes at the bottom, left, top and right. For example:

> opar = par(oma = c(0,0,0,4)) # Large right margin for plot
> mycols = c("tan", "orange1", "magenta", "cyan", "red", "sandybrown")
> barplot(bf, beside = TRUE, col = mycols)
> par(opar) # Reset par

Now you have to set the graphical paramaters again, this time set oma, mar and new = TRUE. The last parameter is important as it does not wipe the plot as the graphical parameters are set. Once you've altered the graphical parameters you can set the legend():

> opar = par(oma = c(0,0,0,0), mar = c(0,0,0,0), new = TRUE)
> legend(x = "right", legend = rownames(bf), fill = mycols, bty = "n", y.intersp = 2)
> par(opar) # Reset par

Legend in the right margin
Altering graphical parameters allows the legend to fit in the plot margin

Note that the fill parameter is set to the same colors as in the plot. Note also that the y.intersp parameter has set a wider space between the legend entries.


Use the inset parameter to shift the legend position away from its default.

If the legend was placed at the "bottom" a positive value moves the legend upwards.

Values range 0-1

Use a small negative value to shift the legend away from the axis labels.

Top

Place a legend in the bottom margin of a plot

The bottom margin of a plot can present some slight difficulties because the axis labels get in the way. The easiest solution is to use the inset parameter and shift the legend outwards (use a small negative value).

Start by making space in the bottom outer margin, then make the basic plot:

> opar = par(oma = c(2,0,0,0))
> barplot(bf, beside = TRUE, col = cm.colors(6))
> par(opar) # Reset par

Now set the margins to zero and set the overplot. The legend() command can now be used with the inset parameter:

> opar =par(oma = c(0,0,0,0), mar = c(0,0,0,0), new = TRUE)
> legend(x = "bottom", legend = rownames(bf), fill = cm.colors(6), bty = "n", ncol = 3, inset = -0.15)
> par(opar) # reset par

Legend in the bottom margin
The inset parameter shifts the legend position slightly, to avoid the axis labels

Note that positive values for inset shift the position upwards, a value of 0.5 is about half-way up. The direction of the inset shift is determined by the position you set in the command. If you used x = "bottom" then positive values shift the position upwards. If you used x = "right" then positive values shift the position left.


When using plots that use pch, lty and col it is best to specify them explicitly in the plotting command.

This makes it easier to match in the legend() command.

Top

Legend in the plot margin for a scatter or line plot

If you use a line plot or a scatter plot you'll have to contend with different plotting characters and line types. It is easier to set the parameters explicitly in the plot() command so that they are more easily matched in the legend().

In the following example a matplot() is used to create a multiple-series line plot. The legend is placed in the right margin.


> t(bf) # Rotate the data as matplot() takes columns as series
M.bro Or.tip Paint.l Pea Red.ad Ring
1996 88 90 50 48 6 190
1997 47 14 0 110 3 80
1998 13 36 0 85 8 96
1999 33 24 0 54 10 179
2000 86 47 4 65 15 145 > mycols = c("tan", "orange1", "magenta", "cyan", "red", "sandybrown")
> opar = par(oma = c(0,0,0,5.5)) # Set right margin
## Plot without axes (because axis labels are numbers) > matplot(t(bf), ylab = "", type = "b", pch = 1:6, lty = 1:6,
axes = FALSE, lwd = 2, col = mycols)
> axis(2) # Use default y-axis
> axis(1, at = 1:5, labels = colnames(bf)) # Custom x-axis using years as labels
> box() # Bounding box around plot
> title(ylab = "Abundance", xlab = "Year")
> par(opar) # Reset par
> opar = par(oma = c(0,0,0,0), mar = c(0,0,0,0), new = TRUE)
> legend(x = "right", legend = rownames(bf), col = mycols,
pch = 1:6, lty = 1:6, bty = "n",
ncol = 1, text.col = "blue", y.intersp = 2) # Legend pars match matplot
> par(opar) # Reset par

Multiple series line plot with custom legend in right margin
The parameters of the plotting command must be matched in the legend

Note that in this example the color of the legend text has also been customized via the text.col parameter. For all the parameters used by legend() type help(legend) into R.


Top
MongRaphs Index

See my Publications about statistics and data analysis.

Writer's Bloc – my latest writing project includes R scripts

Courses in data analysis, data management and statistics.

Follow me...
Facebook Twitter Google+ Linkedin Amazon
Top Home
Data Analysis
MonogRaphs Index Contact