knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>",
  fig.align = 'center',
  fig.height = 3, fig.width = 3
)

plotting

Plot


creating a plot

# a single numeric vector
# elements are plotted against their indices
v <- 1:10
plot(1:10)
# two numeric vectors
vs <- sample(v)
plot(x = v, y = vs)
# a matrix
# the first two columns are plotted as if they were x and y, the others are ignored
m <- matrix(1:12, 4, 3)
m
plot(m)
# a data frame
# every column is plotted against every other, creating a matrix of scatter plots
d <- iris[3:5]
plot(d)


plot content

\newline

plot(v, vs, type = 'p')
plot(v, vs, type = 'l')
plot(v, vs, type = 'b')


plot(1:25, rep(1, 25), pch = 1:25)
plot(1:25, rep(1, 25), pch = 1:5)


plot(v, vs, type = 'l', lty = 1)
plot(v, vs, type = 'l', lty = 2)
plot(v, vs, type = 'l', lty = 3)


# as a hex code
plot(v, vs, pch = 16, col = "#6495ED")
# as a character string
# see colors() for a list of available colors
plot(v, vs, pch = 16, col = "cornflowerblue")
# as a factor; each level is given a color based on the current palette
f <- factor(rep(letters[1:2], each = 5))
plot(v, vs, pch = 16, col = f)
# as an integer, which is interpreted as an index in the current palette
plot(v, vs, pch = 16, col = 2)

NOTE: colorRampPalette is a function that returns a function which takes an integer as argument and returns a vector of that many interpolated colors.

plot(v, vs, pch = 16, col = colorRampPalette(c('royalblue1', 'yellow', 'purple'))(10))


plot(v, vs, xlim = c(-2, 12))


adding content

plot(v, vs)
points(v, sample(v), pch = 20, col = 'green')


plot(log(0:2000 / 100), type = 'l')
abline(h = 0)
plot(log(0:2000 / 100), type = 'l')
abline(h = c(0,1), lty = c(1,2))


plot appearance

plot(v, vs, pch = 16)
# cex alone refers to the plotting characters
plot(v, vs, pch = 16, cex = 2)
# other cex parameters exist for other plot elements
plot(v, vs, pch = 16, cex.lab = 2)


plot(v, vs, xlab = 'label x', ylab = 'label y')


plot(v, vs, main = 'plot title')
plot(v, vs)
title('plot title')


plot(v, vs, col = f, pch = 16)
title('plot title')
legend('topright', legend = levels(f), col = 1:length(levels(f)), pch = 16, cex = 0.75)



plotting area

m <- matrix(c(1, 1, 2, 1, 1, 2, 3, 3, 4), 3, 3, byrow = T)
m

layout(mat = m)
foo <- function() {
  # prepare layout
  layout(mat = m)

  # prepare data
  v1 <- rnorm(1e4)
  v2 <- runif(1e4, -1, 1)
  d1 <- density(v1)
  d2 <- density(v2)
  names(d2) <- c(names(d2)[2], names(d2)[-2])

  # draw plots
  plot(v1, v2, pch = 4, cex = 0.5)
  plot(d2, main = '', xlab = '', ylab = '')
  plot(d1, main = '', xlab = '', ylab = '')
  # draw an empty plot in field 16
  plot.new()
}

foo()

\newline

layout(mat = 1)




Other Plot Types


plot(rnorm(1e4), runif(1e4), pch = 4, cex = 0.2)
smoothScatter(rnorm(1e4), runif(1e4), pch = 4, cex = 0.2)


# a vector
barplot(v)
# a matrix
barplot(m)
barplot(m, beside = T)


# a vector
rv <- rnorm(1e2)
stripchart(rv, pch = 20)
stripchart(rv, method = 'jitter', pch = 20)

# a data frame
stripchart(iris[1:4], method = 'jitter', vertical = T, pch = 1)

NOTE: This is implemented better in package beeswarm.


# a vector
boxplot(rnorm(1e3))
# a matrix
boxplot(as.matrix(iris[1:4]))
#a data frame
boxplot(iris[1:4])


hist(rnorm(1e5))
hist(rnorm(1e5), breaks = 100)
persp(volcano)
contour(volcano)
image(volcano)




Plotting With Formulas


formulas in plot

# numeric vs numeric draws a scatter plot
plot(Sepal.Length ~ Sepal.Width, data = iris, col = Species, pch = 20)
# numeric vs factor drawas a boxplot
plot(Sepal.Length ~ Species, data = iris, col = Species)
# two terms on RHS draws two plots
plot(Sepal.Length ~ Petal.Length + Petal.Width, data = iris)
# plot one column vs all others
plot(Sepal.Length ~ ., data = iris, col = Species, pch = 20)


formulas in other plotting functions

barplot(yield ~ variety + year, data = lattice::barley, subset = site == 'Morris', beside = TRUE)
stripchart(Sepal.Length ~ Species, data = iris, vertical = T, method = 'jitter', pch = 1)
boxplot(Sepal.Length ~ Species, data = iris)


enhanced use of formulas

coplot(Sepal.Length ~ Sepal.Width | Species, data = iris, pch = 16, rows = 1)
library(lattice)
xyplot(Sepal.Length ~ Petal.Width | Species, data = iris, layout = c(3,1))
stripplot(yield ~ year | site, data = barley, layout = c(3,2))
bwplot(yield ~ year | variety, data = barley, layout = c(5,2))
bwplot(Sepal.Length ~ Species, data = iris)
histogram(~ Sepal.Length | Species, data = iris, layout = c(3,1))
levelplot(Sepal.Length ~ Petal.Width * Petal.Length | Species, data = datasets::iris, layout = c(3,1),
          at = seq(4, 8, length.out = 100), col.regions = colorRampPalette(c('blue', 'gray90', 'red'))(100),
          aspect = 1)

NOTE: lattice plots ignore some par commands, e.g. title, layout.

ALSO NOTE: lattice plots are only drawn automaticaly when in an interactive session. Otherwise they must be drawn explicitly with print.




Saving Plots To Files

The simplest way to save a plot to a file is to draw it in RStudio viewer and press the "Export file" button in the viewer but where is the fun in that? You will also find the viewer rather slow in some cases.

graphics devices

R has a system of devices that graphics is streamed to. The default device is the null device. Graphics sent to the null device ends up in the RStudio viewer in the Plots tab. Other devices can be opened at any time to send the graphics to a file. Opening a new device creates a file to capture the incoming graphics. That device becomes the current device, where the graphics will be sent now. Functions that open devices include jpeg, png and pdf, each for the corresponing file type.

All currently open devices can be viewed with dev.list(). A newly open device is added to the end of the list and becomes the current one. It can be viewed with dev.cur(). There are ways to switch between devices but that is rarely done. Usually one opens a device, streams the graphics and closes the device immediately after.

Devices are closed with the dev.off function. It will close the device specified by a number, that device's number on the list. Called without an argument, dev.off(), it will close the current device. Only when a device is closed is the corresponding file saved. Attempts to manipulate the file before that will throw errors. Opening a stream to a file that is already associated with a graphics device, which can happen when plotting fails and one wants to immediately try again, is a sure way to trouble. Sometimes a dev.off() needs to be redoubled.

graphics.off closes all open devices. The null device can never be closed. graphics.off() skips it and dev.off(1) throws an error. Calling dev.off() on a null device will also clear the plots from RStudio memory.


printing plots

To print a plot to a file open a device with, say, png, draw a plot as you normally would in RStudio, and call dev.off() to close the file. Unlike in RStudio, past plots are not available for rewinding. Only the last plot is saved to the file. The pdf device behaves differently. It has an onefile argument, which is set to TRUE by default. With the pdf device plots will be added to the file, one plot per page. Again, the graphics cannot be viewed before the device is closed.

Also, .pdf files are saved as vetor graphics rather than rasters. You can open them in Corel or Illustrator and edit particular elements there with no loss of quality.




olobiolo/Rdlazer documentation built on Aug. 6, 2022, 11:37 a.m.