Plotting Fundamentals – Complex Grid Layouts

Complex Grid Layouts

Several methods for modifying base graphics were shown in Chapter 3 of Introductory Fisheries Analyses with R (IFAR), including simple layouts (side-by-side, one-over-the-other) of multiple plots. More complex layouts (e.g., plot in first row spans two columns or unequal sized plots) are described in this supplement. Creating common x- and y-axis labels for a grid of plots is described in this supplement.

Required Packages for this Supplement

Functions used in this supplement require the packages shown below.

> library(FSAdata)
> library(FSA)
> library(dplyr)

Data Used in this Supplement

The BullTroutRML2 and BloaterLH data from FSAdata used in the IFAR book are also used in this supplement.

> data(BullTroutRML2)
> BT <- BullTroutRML2
> headtail(BT)
   age  fl     lake     era
1   14 459 Harrison 1977-80
2   12 449 Harrison 1977-80
3   10 471 Harrison 1977-80
94   4 298   Osprey 1997-01
95   3 279   Osprey 1997-01
96   3 273   Osprey 1997-01
> data(BloaterLH)
> BLH <- BloaterLH
> headtail(BLH)
   year   eggs    age3
1  1981 0.0402   5.143
2  1982 0.0602 154.286
3  1983 0.1205  65.143
14 1994 0.8434  13.714
15 1995 1.0141   0.000
16 1996 1.0241   3.429

 

Complex Grid Layouts with layout()

The layout() function allows for more complicated organizations of plots. The only required argument to layout() is a matrix that specifies the positions, as a grid, for a series of plots. The numbers in the matrix describe which sequential plot will appear in that position. For example, the following code constructs a 2×2 grid for four plots where the first plot will appear in the lower-right corner and the last (fourth) plot will appear in the upper-left corner.

> ( m <- matrix(4:1,nrow=2,byrow=TRUE) )
     [,1] [,2]
[1,]    4    3
[2,]    2    1
> layout(m)

The layout.show() function is used to show the layout grid. Its only argument is the number of positions to show. The example below illustrates the layout created above.

> layout.show(4)

Figure 1: Illustration of 2×2 layout grid for graphics.

The 2×2 grid in Figure 1 is not that interesting because that layout is just as easily constructed with mfrow= in par() (as shown in the IFAR book). Layouts, however, can also be constructed that are not “grids.” For example, the entire first row may be one plot with a second row of two plots. This layout grid is constructed by including a “1” in the first two positions of the layout matrix (Figure 2).

> ( m <- matrix(c(1,1,2,3),nrow=2,byrow=TRUE) )
     [,1] [,2]
[1,]    1    1
[2,]    2    3
> layout(m)
> layout.show(3)

Figure 2: Illustration of layout grid for graphics with one plot in the first row and two in the second row.

The following code fills this layout grid to produce Figure 3.

> plot(age3~eggs,data=BLH,pch=19,xlab="Millions of Eggs",
       ylab="Relative Abundance of Age-3 Fish")
> hist(~eggs,data=BLH,xlab="Millions of Eggs")
> hist(~age3,data=BLH,xlab="Age-3 Relative Abundance")

Figure 3: Illustration of a plot with one subplot in the first row and two in the second row.

The size of the plots in the layout may be controlled with height= and width=. These arguments accept vectors that represent the relative heights and widths of the rows and columns in the layout grid, respectively. For example, height=c(3,1) sets the height of the first row to be three times larger than the height of the second row. Including the respect=TRUE argument will assure that “unit distances” in the horizontal and vertical directions are treated the same. An example layout with different cell sizes is constructed below and shown in Figure 4. Also note in this example, that a zero in a cell means that that cell will not receive a plot.

> ( m <- matrix(c(2,0,1,3),nrow=2,byrow=TRUE) )
     [,1] [,2]
[1,]    2    0
[2,]    1    3
> layout(m,height=c(1,4),width=c(4,1),respect=TRUE)
> layout.show(3)

Figure 4: Illustration of layout grid for plots with differing row heights and column widths.

Figure 5 is an example that fills the layout shown in Figure 4.

> par(mar=c(4,4,0,0))
> plot(age3~eggs,data=BLH,xlim=c(0,2.4),ylim=c(0,240),pch=19,
       ylab="Relative Abundance of Age-3 Fish",
       xlab="Millions of Eggs")
> par(mar=c(0,4,0,0))
> boxplot(BLH$eggs,axes=FALSE,ylim=c(0,2.4),horizontal=TRUE)
> par(mar=c(4,0,0,0))
> boxplot(BLH$age3,axes=FALSE,ylim=c(0,240))

Figure 5: Illustration of layout grid with differing heights and widths such that a scatterplot appears in the ‘middle’ with corresponding boxplots on the ‘sides.’

Finally, layout() may be used to make quite complex grids, as illustrated with the code below that produced Figure 6. Note that plot.new() creates a new blank plot in which the subsequent text() commands will place text (in this case marginal labels).

> BTH1 <- BT %>% filterD(lake=="Harrison",era=="1977-80")
> BTO1 <- BT %>% filterD(lake=="Osprey",era=="1977-80")
> BTH2 <- BT %>% filterD(lake=="Harrison",era=="1997-01")
> BTO2 <- BT %>% filterD(lake=="Osprey",era=="1997-01")
> 
> ( m <- matrix(c(0,1,2,3,5,6,4,7,8),nrow=3,byrow=TRUE) )
     [,1] [,2] [,3]
[1,]    0    1    2
[2,]    3    5    6
[3,]    4    7    8
> layout(m,height=c(1,8,8),width=c(1,8,8),respect=TRUE)
> 
> par(mar=c(0,0,0,0))
> plot.new(); text(0.5,0.5,"Harrison",cex=1.5)
> plot.new(); text(0.5,0.5,"Osprey",cex=1.5)
> plot.new(); text(0.5,0.5,"Era = 1977-1980",cex=1.5,srt=90)
> plot.new(); text(0.5,0.5,"Era = 1997-2001",cex=1.5,srt=90)
> 
> par(mar=c(3.05,3.05,0.65,0.65),mgp=c(1.7,0.5,0))
> xlmt <- c(-0.5,14.5)
> ylmt <- c(0,700)
> plot(fl~age,data=BTH1,xlab="",ylab="Fork Length",
       pch=19,xlim=xlmt,ylim=ylmt)
> plot(fl~age,data=BTO1,xlab="",ylab="",
       pch=19,xlim=xlmt,ylim=ylmt)
> plot(fl~age,data=BTH2,xlab="Age",ylab="Fork Length",
       pch=19,xlim=xlmt,ylim=ylmt)
> plot(fl~age,data=BTO2,xlab="Age",ylab="",
       pch=19,xlim=xlmt,ylim=ylmt)

Figure 6: Illustration of layout grid with differing heights and widths such that labels can be placed on the sides.

 


Reproducibility Information

  • Compiled Date: Thu Nov 05 2015
  • Compiled Time: 6:47:39 PM
  • R Version: R version 3.2.2 (2015-08-14)
  • System: Windows, i386-w64-mingw32/i386 (32-bit)
  • Base Packages: base, datasets, graphics, grDevices, methods, stats, utils
  • Required Packages: FSAdata, FSA, dplyr, captioner, knitr and their dependencies (assertthat, car, DBI, digest, evaluate, formatR, gdata, gplots, graphics, grDevices, highr, Hmisc, lazyeval, magrittr, markdown, methods, plotrix, plyr, R6, Rcpp, sciplot, stats, stringr, tools, utils, yaml)
  • Other Packages: captioner_2.2.3, dplyr_0.4.3, extrafont_0.17, FSA_0.8.4, FSAdata_0.3.2, knitr_1.11, magrittr_1.5, rmarkdown_0.8.1, stringr_1.0.0, tidyr_0.3.1
  • Loaded-Only Packages: assertthat_0.1, DBI_0.3.1, digest_0.6.8, evaluate_0.8, extrafontdb_1.0, formatR_1.2.1, gdata_2.17.0, gtools_3.5.0, highr_0.5.1, htmltools_0.2.6, lazyeval_0.1.10, parallel_3.2.2, plyr_1.8.3, R6_2.1.1, Rcpp_0.12.1, Rttf2pt1_1.3.3, stringi_1.0-1, tools_3.2.2, yaml_2.1.13
  • Links: Script / RMarkdown