The layout() Function
The ability to manage multiple plots in one graphical device or window is a key capability to enhance data visualization and analysis.
The layout() function in base R is the most straightforward method to divide a graphical device into rows and columns. The function requires an input matrix definition. Column-widths and the row-heights can be defined using additional input arguments. layout.show() can then be used to see multi-graph layouts and how the graphical device is being split.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
[code lang="r"] # Save original device parameters for reset op=par() # Define data x <- pmin(3, pmax(-3, stats::rnorm(50))) y <- pmin(3, pmax(-3, stats::rnorm(50))) xhist <- hist(x, breaks = seq(-3,3,0.5), plot = FALSE) yhist <- hist(y, breaks = seq(-3,3,0.5), plot = FALSE) top <- max(c(xhist$counts, yhist$counts)) xrange <- c(-3, 3) yrange <- c(-3, 3) # Using the layout() function nf <- layout(matrix(c(2,0,1,3),2,2,byrow = TRUE), c(3,1), c(1,3),TRUE) layout.show(nf) # Configure base graphics device and generate plots par(mar = c(3,3,1,1)) plot(x, y, xlim = xrange, ylim = yrange, xlab = "", ylab = "", pch = 15, col = "blue") par(mar = c(0,3,1,1)) barplot(xhist$counts, axes = FALSE, ylim = c(0, top), space = 0, col = "green") par(mar = c(3,0,1,1)) barplot(yhist$counts, axes = FALSE, xlim = c(0, top), space = 0, horiz = TRUE, col = "green") # Reset device parameters par(op) |
Using par() Arguments for Multi-Graph Layouts
The alternative method for launching multi-plots in base R is to use the functions mfrow() and mfcol(). Use just one of the functions to define a plot layout given the vector argument c(nrow, ncol) to define an nrow by ncol array on the graphical device. The option function mfg() is then used to control plotting by array element. Specifically, mfg() takes the argument c(i, j) , where the i and j indicate which figure in the array is to be drawn.
1 2 3 4 5 |
par(mfrow = c(2,2), oma = c(0.5, 0.5, 0.5, 0.5)) plot(rnorm(10), type = "p", col="blue", main = "Points") plot(rnorm(10), type = "l", col="blue", main = "Line") plot(rnorm(10), type = "b", col="blue", main = "Points & Line A") plot(rnorm(10), type = "o", col="blue", main = "Points & Line B") |
1 2 3 4 5 6 7 8 9 10 |
# Draw a 2x2 plot and change plot order using mfg() par(mfrow = c(2,2), oma = c(0.5, 0.5, 0.5, 0.5)) par(mfg = c(2, 1)) plot(rnorm(10), type = "p", col="blue", main = "Points") par(mfg = c(2, 2)) plot(rnorm(10), type = "l", col="blue", main = "Line") par(mfg = c(1, 2)) plot(rnorm(10), type = "b", col="blue", main = "Points & Line A") par(mfg = c(1, 1)) plot(rnorm(10), type = "o", col="blue", main = "Points & Line B") |
In general, the mfrow() and mfcol() functions are much more rigid and less flexible than the layout() function. Having said that, each approach can be useful.