# 12 Plots from Scratch

In this chapter we describe one of my favorite graphing approaches to create what I like to call plots from scratch. That is, making a graph in a way that we have full control of all the nitty-gritty details of a plot.

## 12.1 Making a graphic from scratch

In addition to using plot(), possibly calling one or more low-level functions, you should know that it is also possible to create a plot from scratch. Although this procedure is less documented, it is extremely flexible and powerful. The general recipe to create a plot with this approach is as follows:

• call plot.new() to start a new plot frame

• call plot.window() to define coordinates

• then call low-level functions:

• typical options involve axis()

• then title() (title, subtitle)

• after that call other function: e.g. points(), lines(), etc

plot.new()
plot.window(xlim = c(0, 10), ylim = c(-2, 4), xaxs = "i")
axis(side = 1, col.axis = "grey30")
axis(side = 2, col.axis = "grey30", las = 1)
title(main = "Main Title",
col.main = "tomato",
sub = "Plot Subtitle",
col.sub = "orange",
xlab = "x-axis",
ylab = "y-axis",
col.lab = "blue",
font.lab = 3)
box("figure", col = "grey90")

Here’s another example:

set.seed(5)
x <- rnorm(200)
y <- x + rnorm(200)

plot.new()
plot.window(xlim = c(-4.5, 4.5), xaxs = "i",
ylim = c(-4.5, 4.5), yaxs = "i")
z <- lm(y ~ x)
abline(h = -4:4, v = -4:4, col = "lightgrey")
abline(a = coef(z)[1], b = coef(z)[2], lwd = 2, col = "red")
points(x, y)
axis(side = 1)
axis(side = 2, las = 1)
box()
title(main = "A Fitted Regression Line")

### 12.1.1 How does it work

You start a new plot with plot.new()

• plot.new() opens a new (empty) plot frame

• plot.new() chooses a default plotting region

After starting with plot.new(), use plot.window() to set up the coordinate system for the plotting frame

# axis limits (0,1)x(0,1)
plot.window(xlim = c(0, 1), ylim = c(0, 1))

By default plot.window() produces axis limits which are expanded by 6% over those actually specified.

The default limits expansion can be turned-off by specifying xaxs = "i" and/or yaxs = "i"

plot.window(xlim, ylim, xaxs = "i")

#### Aspect Ratio Control

Another important argument is asp, which allows us to specify the aspect ratio

plot.window(xlim, ylim, xaxs = "i", asp = 1)

asp = 1 means that unit steps in the x and y directions produce equal distances in the x and y directions on the plot.

(Important for avoiding distortion of circles that look like ellipses)

#### Drawing Axes

The axis() function can be used to draw axes at any of the four sides of a plot.

• side = 1 below the graph

• side = 2 to the left of the graph

• side = 3 above the graph

• side = 4 to the right of the graph

Axes can be customized via several arguments (see ?axis)

• location of tick-marks

• labels of axis

• colors

• sizes

• text fonts

• text orientation

#### Plot Annotatiosn

The function title() allows us to include labels in the margins

• main main title above the graph

• sub subtitle below the graph

• xlab label for the x-axis

• ylab label for the y-axis

The annotations can be customized with additional arguments for the fonts, colors, and size (expansion)

• font.main, col.main, cex.main

• font.sub, col.sub, cex.sub

• font.lab, col.lab, cex.lab

### 12.1.2 Drawing Arrows

plot.new()
plot.window(xlim = c(0, 1), ylim = c(0, 1))
arrows(0.05, 0.075, 0.45, 0.9, code = 1)
arrows(0.55, 0.9, 0.95, 0.075, code = 2)
arrows(0.1, 0, 0.9, 0, code = 3)
text(0.5, 1, "A", cex = 1.5)
text(0, 0, "B", cex = 1.5)
text(1, 0, "C", cex = 1.5)

### 12.1.3 Drawing Rectangles

Rectangles can be drawn with the function:

rect(x0, y0, x1, y1, col = str, border = str)
• x0, y0, x1, y1 give the coordinates of diagonally opposite corners of the rectangles/

• col specifies the color of the interior.

• border specifies the color of the border/

# barplot "manually" constructed
plot.new()
plot.window(xlim = c(0, 5), ylim = c(0, 10))
rect(0:4, 0, 1:5, c(7, 8, 4, 3),
col = "turquoise",
border = "white")
axis(1)
axis(2, las = 1)