Plot in R
The most basic graphics function in R is the plot
function. This function has multiple arguments to configure the final plot: add a title, change axes labels, customize colors, or change line types, among others. In this tutorial you will learn how to plot in R and how to fully customize the resulting plot.
Plot function in R
The R plot
function allows you to create a plot passing two vectors (of the same length), a dataframe, matrix or even other objects, depending on its class or the input type. We are going to simulate two random normal variables called x
and y
and use them in almost all the plot examples.
set.seed(1)
# Generate sample data
x <- rnorm(500)
y <- x + rnorm(500)
You can create a plot of the previous data typing:
# Plot the data
plot(x, y)
# Equivalent
M <- cbind(x, y)
plot(M)
With the plot
function you can create a wide range of graphs, depending on the inputs. In the following table we summarize all the available possibilities for the base R plotting function.
Function and arguments | Output plot |
---|---|
plot(x, y) | Scatterplot of x and y numeric vectors |
plot(factor) | Barplot of the factor |
plot(factor, y) |
Boxplot of the numeric vector and the levels of the factor |
plot(time_series) | Time series plot |
plot(data_frame) |
Correlation plot of all dataframe columns (more than two columns) |
plot(date, y) | Plots a date-based vector |
plot(function, lower, upper) |
Plot of the function between the lower and maximum value specified |
If you execute the following code you will obtain the different plot examples.
# Examples
par(mfrow = c(2, 3))
# Data
my_ts <- ts(matrix(rnorm(500), nrow = 500, ncol = 1),
start = c(1950, 1), frequency = 12)
my_dates <- seq(as.Date("2005/1/1"), by = "month", length = 50)
my_factor <- factor(mtcars$cyl)
fun <- function(x) x^2
# Scatterplot
plot(x, y, main = "Scatterplot")
# Barplot
plot(my_factor, main = "Barplot")
# Boxplot
plot(my_factor, rnorm(32), main = "Boxplot")
# Time series plot
plot(my_ts, main = "Time series")
# Time-based plot
plot(my_dates, rnorm(50), main = "Time based plot")
# Plot R function
plot(fun, 0, 10, main = "Plot a function")
# Correlation plot
plot(trees[, 1:3], main = "Correlation plot")
par(mfrow = c(1, 1))
When you create several plots in R GUI (not in RStudio), the next plot will override the previous. However, you can create new plot windows with windows
, X11
and quartz
functions depending on your operating system, to solve this issue.
R window
When creating plots in base R they will be opened in a new window. However, you may need to customize the height and width of the window, that defaults to 7 inches (17.78 cm). For that purpose, you can use of the height
and width
arguments of the following functions, depending on your system.
It should be noted that in RStudio the graph will be displayed in the pane layout but if you use the corresponding function, the graph will open in a new window, just like in base R.
windows() # Windows
X11() # Unix
quartz() # Mac
In addition to being able to open and set the size of the window, this functions are used to avoid overriding the plots you create, as when creating a new plot you will lose the previous. Note that in RStudio you can navigate through all the plots you created in your session in the plots pane.
# First plot will open
# a new window
plot(x, y)
# New window
windows()
# Other plot in new window
plot(x, x)
You can also clear the plot window in R programmatically with dev.off
function, to clear the current window and with graphics.off
, to clear all the plots and restore the default graphic parameters.
# Clear the current plot
dev.off()
# Clear all the plots
graphics.off()
while (dev.cur() > 1) dev.off() # Equivalent
Note that the dev.cur
function counts the number of current available graphics devices.
R plot type
You can also customize the plot type with the type
argument. The selection of the type will depend on the data you are plotting. In the following code block we show the most popular plot types in R.
j <- 1:20
k <- j
par(mfrow = c(1, 3))
plot(j, k, type = "l", main = "type = 'l'")
plot(j, k, type = "s", main = "type = 's'")
plot(j, k, type = "p", main = "type = 'p'")
par(mfrow = c(1, 1))
par(mfrow = c(1, 3))
plot(j, k, type = "l", main = "type = 'o'")
plot(j, k, type = "s", main = "type = 'b'")
plot(j, k, type = "p", main = "type = 'h'")
par(mfrow = c(1, 1))
Plot type | Description |
---|---|
p | Points plot (default) |
l | Line plot |
b | Both (points and line) |
o | Both (overplotted) |
s | Stairs plot |
h | Histogram-like plot |
n | No plotting |
R plot pch
The pch
argument allows to modify the symbol of the points in the plot. The main symbols can be selected passing numbers 1 to 25 as parameters. You can also change the symbols size with the cex
argument and the line width of the symbols (except 15 to 18) with the lwd
argument.
r <- c(sapply(seq(5, 25, 5), function(i) rep(i, 5)))
t <- rep(seq(25, 5, -5), 5)
plot(r, t, pch = 1:25, cex = 3, yaxt = "n", xaxt = "n",
ann = FALSE, xlim = c(3, 27), lwd = 1:3)
text(r - 1.5, t, 1:25)
Note that symbols 21 to 25 allow you to set border width and also background color with the lwd
and bg
arguments, respectively.
plot(r, t, pch = 21:25, cex = 3, yaxt = "n", xaxt = "n", lwd = 3,
ann = FALSE, xlim = c(3, 27), bg = 1:25, col = rainbow(25))
In the following block of code we show a simple example of how to customize one of these symbols.
# Example
plot(x, y, pch = 21,
bg = "red", # Fill color
col = "blue", # Border color
cex = 3, # Symbol size
lwd = 3) # Border width
It is worth to mention that you can use any character as symbol. In fact, some character symbols can be selected using numbers 33 to 240 as parameter of the pch
argument.
# Custom symbols
plot(1:5, 1:5, pch = c("☺", "❤", "✌", "❄", "✈"),
col = c("orange", 2:5), cex = 3,
xlim = c(0, 6), ylim = c(0, 6))
R plot title
The title can be added to a plot with the main
argument or the title
function.
plot(x, y, main = "My title")
# Equivalent
plot(x, y)
title("My title")
The main difference between using the title
function or the argument is that the arguments you pass to the function only affect the title.
In order to change the plot title position you can set the adj
argument with a value between 0 (left) and 1 (right) and the line
argument, where values greater than 1.7 (default) move the title up and values lower than 1.7 to move it down. Negative values of line
will make the title go inside the plot. It should be noted that if you set this arguments to the plot
function, the changes will be applied to all texts.
plot(x, y)
title("My title",
adj = 0.75, # Title to the right
line = 0.25)
LaTeX in plot title
It is very common for data scientists the need of display mathematical expressions in the title of the plots. For that purpose, you can use the expression
function. You can look for all the available options for using LaTeX-like mathematical notation calling ?plotmath
.
plot(x, y, main = expression(alpha[1] ^ 2 + frac(beta, 3)))
Nevertheless, the syntax of the function is quite different from LaTeX syntax. If you prefer, you can use the TeX
function of the latex2exp
package. However, note that this function translates TeX notation to expression
function notation, so the symbols and notation available are the same in both functions.
# install.packages("latex2exp")
library(latex2exp)
plot(x, y, main = TeX('$\beta^3, \beta \in 1 \ldots 10$'))
The LaTeX expressions can be used also in the subtitle, axis labels or any other place, as text added to the plot.
Subtitle in R plot
Furthermore, you can add a subtitle to a plot in R with the sub
argument, that will be displayed under the plot. It is possible to add a subtitle even if you don’t specify a title.
plot(x, y, main = "My title", sub = "My subtitle")
# Equivalent
plot(x, y)
title(main = "My title", sub = "My subtitle")
Axis in R
In R plots you can modify the Y and X axis labels, add and change the axes tick labels, the axis size and even set axis limits.
R plot x and y labels
By default, R will use the vector names of your plot as X and Y axes labels. However, you can change them with the xlab
and ylab
arguments.
plot(x, y, xlab = "My X label", ylab = "My Y label")
If you want to delete the axes labels you can set them to a blank string or set the ann
argument to FALSE
.
# Delete labels
plot(x, y, xlab = "", ylab = "")
# Equivalent
plot(x, y, xlab = "My X label", ylab = "My Y label", ann = FALSE)
R axis function
The argument axes
of the plot
function can be set to FALSE
in order to avoid displaying the axes, so in case you want, you can add only one of them with the axis
function and customize it. Passing a 1
as argument will plot the X-axis, passing 2
will plot the Y-axis, 3
is for the top axis and 4
for the right axis.
plot(x, y, axes = FALSE)
# Add X-axis
axis(1)
# Add Y-axis
axis(2)
Change axis tick-marks
It is also possible to change the tick-marks of the axes. On the one hand, the at
argument of the axis
function allows to indicate the points at which the labels will be drawn.
plot(x, y, axes = FALSE)
axis(1, at = -2:2)
On the other hand, the minor.tick
function of the Hmisc
package allows you to create smaller tick-marks between the main ticks.
# install.packages("Hmisc")
library(Hmisc)
plot(x, y)
minor.tick(nx = 3, ny = 3, tick.ratio = 0.5)
Finally, you could create interior ticks specifying a positive number in the tck
argument as follows:
# Interior ticks
plot(x, y, tck = 0.02)
Remove axis tick labels
Setting the arguments xaxt
or yaxt
to "n"
of the plot
function will avoid plotting the X and Y axis labels, respectively.
par(mfrow = c(1, 3))
# Remove X axis tick labels
plot(x, y, xaxt = "n", main = "xaxt = 'n'")
# Remove Y axis tick labels
plot(x, y, yaxt = "n", main = "yaxt = 'n'")
# Remove both axis tick labels
plot(x, y, yaxt = "n", xaxt = "n", main = "xaxt = 'n', yaxt = 'n'")
par(mfrow = c(1, 1))
Change axis tick labels
The axes tick labels will be numbered to follow the numeration of your data. Nevertheless, you can modify the tick labels, if needed, with the labels
argument of the axis
function. You will also have to specify where the tick labels will be displayed with the at
argument.
par(mfrow = c(1, 2))
# Change X axis tick labels
plot(x, y, xaxt = "n")
axis(1, at = seq(round(min(x)), round(max(x)), by = 1), labels = 1:8)
# Change Y axis tick labels
plot(x, y, yaxt = "n")
axis(2, at = seq(round(min(y)), round(max(y)), by = 1), labels = 1:9)
Rotate axis labels
The las
argument of the plot
function in R allows you to rotate the axes labels of your plots. In the following code block you will find the explanation of the different alternatives.
par(mfrow = c(2, 2))
plot(x, y, las = 0, main = "Parallel") # Parallel to axis (default)
plot(x, y, las = 1, main = "Horizontal") # Horizontal
plot(x, y, las = 2, main = "Perpendicular") # Perpendicular to axis
plot(x, y, las = 3, main = "Vertical") # Vertical
par(mfrow = c(1, 1))
Set axis limits
You can zoom in or zoom out the plot changing R plot axes limits. These arguments are very useful to avoid cropping lines when you add them to your plot.
plot(x, y,
ylim = c(-8, 8), # Y-axis limits from -8 to 8
xlim = c(-5, 5)) # X-axis limits from -5 to 5
Change axis scale in R
The log
argument allows changing the scale of the axes of a plot. You can transform the X-axis, the Y-axis or both as follows:
# New data to avoid negative numbers
s <- 1:25
u <- 1:25
par(mfrow = c(2, 2))
# Default
plot(s, u, pch = 19,
main = "Untransformed")
# Log scale. X-axis
plot(s, u, pch = 19, log = "x",
main = "X-axis transformed")
# Log scale. Y-axis
plot(s, u, pch = 19, log = "y",
main = "Y-axis transformed")
# Log scale. X and Y axis
plot(s, u, pch = 19, log = "xy",
main = "Both transformed")
Log | Transformation |
---|---|
“x” | X-axis transformed |
“y” | Y-axis transformed |
“xy” | Both axis transformed |
However, you may be thinking that using the log
function is equivalent but is not. As you can see in the previous plot, using the log
argument doesn’t modify the data, but the log
function will transform it. Look at the difference between the axes of the following graph and those of the previous one.
par(mfrow = c(1, 3))
# Log-log
plot(log(s), log(u), pch = 19,
main = "log-log")
# log(x)
plot(log(s), u, pch = 19,
main = "log(x)")
# log(y)
plot(s, log(u), pch = 19,
main = "log(y)")
par(mfrow = c(1, 1))
R plot font
Font size
You can also change the font size in an R plot with the cex.main
, cex.sub
, cex.lab
and cex.axis
arguments to change title, subtitle, X and Y axis labels and axes tick labels, respectively. Note that greater values will display larger texts.
plot(x, y, main = "My title", sub = "Subtitle",
cex.main = 2, # Title size
cex.sub = 1.5, # Subtitle size
cex.lab = 3, # X-axis and Y-axis labels size
cex.axis = 0.5) # Axis labels size
Argument | Description |
---|---|
cex.main | Sets the size of the title |
cex.sub | Sets the size of the subtitle |
cex.lab | Sets the X and Y axis labels size |
cex.axis | Sets the tick axis labels size |
Font style
Furthermore, you can change the font style of the R plots with the font
argument. You can set this argument to 1 for plain text, 2 to bold (default), 3 italic and 4 for bold italic text. This argument won’t modify the title style.
par(mfrow = c(1, 3))
plot(x, y, font = 2, main = "Bold") # Bold
plot(x, y, font = 3, main = "Italics") # Italics
plot(x, y, font = 4, main = "Bold italics") # Bold italics
par(mfrow = c(1, 1))
You can also specify the style of each of the texts of the plot with the font.main
, font.sub
, font.axis
and font.lab
arguments.
plot(x, y,
main = "My title",
sub = "Subtitle",
font.main = 1, # Title font style
font.sub = 2, # Subtitle font style
font.axis = 3, # Axis tick labels font style
font.lab = 4) # Font style of X and Y axis labels
Note that, by default, the title of a plot is in bold.
Font style | Description |
---|---|
1 | Plain text |
2 | Bold |
3 | Italic |
4 | Bold italic |
Font family
The family
argument allows you to change the font family of the texts of the plot. You can even add more text with other font families. Note that you can see the full list of available fonts in R with the names(pdfFonts())
command, but some of them may be not installed on your computer.
# All available fonts
names(pdfFonts())
plot(x, y, family = "mono")
text(-2, 3, "Some text", family = "sans")
text(-2, 2, "More text", family = "serif")
text(1, -4, "Other text", family = "HersheySymbol")
An alternative is to use the extrafont
package.
# install.packages("extrafont")
library(extrafont)
# Auto detect the available fonts in your computer
# This can take several minutes to run
font_import()
# Font family names
fonts()
# Data frame containing the font family names
fonttable()
R plot color
In the section about pch
symbols we explained how to set the col
argument, that allows you to modify the color of the plot symbols. In R, there is a wide variety of color palettes. With the colors
function you can return all the available base R colors. Furthermore, you could use the grep
function (a regular expression function) to return a vector of colors containing some string.
# Return all colors
colors()
# Return all colors that contain the word 'green'
cl <- colors()
cl[grep("green", cl)]
# Plot with blue dots
plot(x, y, col = "blue")
plot(x, y, col = 4) # Equivalent
plot(x, y, col = "#0000FF") # Equivalent
You can specify colors with its name ("red"
, "green"
, …), with numbers (1 to 8) or even with its HEX reference ("#FF0000"
, "#0000FF"
, …).
You can also modify the text colors with the col.main
, col.sub
, col.lab
and col.axis
functions and even change the box color with the fg
argument.
plot(x, y, main = "Title", sub = "Subtitle",
pch = 16,
col = "red", # Symbol color
col.main = "green", # Title color
col.sub = "blue", # Subtitle color
col.lab = "sienna2", # X and Y-axis labels color
col.axis = "maroon4", # Tick labels color
fg = "orange") # Box color
Plot color points by group
If you have numerical variables labelled by group, you can plot the data points separated by color, passing the categorical variable (as factor) to the col
argument. The colors will depend on the factors.
# Create dataframe with groups
group <- ifelse(x < 0 , "car", ifelse(x > 1, "plane", "boat"))
df <- data.frame(x = x, y = y, group = factor(group))
# Color by group
plot(df$x, df$y, col = df$group, pch = 16)
# Change group colors
colors <- c("red", "green", "blue")
plot(df$x, df$y, col = colors[df$group], pch = 16)
# Change color order, changing levels order
plot(df$x, df$y, col = colors[factor(group, levels = c("car", "boat", "plane"))],
pch = 16)
Note that, by default, factor levels are ordered alphabetically, so in this case the order of the colors vector is not the order of the colors in the plot, as the first row of the dataframe corresponds to “car”, that is the second level. Hence, if you change the levels order, you can modify the colors order.
Since R 4.0.0 the stringAsFactors
argument of the data.frame
function is FALSE
by default, so you will need to transform the categorical variable into a factor to color the observations by group as in the previous example.
Background color
There are two ways to change the background color of R charts: changing the entire color, or changing the background color of the box. To change the full background color you can use the following command:
# Light gray background color
par(bg = "#f7f7f7")
# Add the plot
plot(x, y, col = "blue", pch = 16)
# Back to the original color
par(bg = "white")
However, the result will be more beautiful if only the box is colored in a certain color, although this requires more code. Note that the plot.new
function allows you to create an empty plot in R and that par (new = TRUE)
allows you to add one graph over another.
# Create an empty plot
plot.new()
rect(par("usr")[1], par("usr")[3],
par("usr")[2], par("usr")[4],
col = "#f7f7f7") # Color
par(new = TRUE)
plot(x, y, col = "blue", pch = 16)
R plot line
You can add a line to a plot in R with the lines
function. Consider, for instance, that you want to add a red line to a plot, from (-4, -4) to (4, 4), so you could write:
plot(x, y)
lines(-4:4, -4:4, lwd = 3, col = "red")
R plot line width
The line width in R can be changed with the lwd
argument, where bigger values will plot a wider line.
M <- matrix(1:36, ncol = 6)
matplot(M, type = c("l"), lty = 1, col = "black", lwd = 1:6)
# Just to indicate the line widths in the plot
j <- 0
invisible(sapply(seq(4, 40, by = 6),
function(i) {
j <<- j + 1
text(2, i, paste("lwd =", j))}))
Plot line type
When plotting a plot of type “l”, “o”, “b”, “s”, or when you add a new line over a plot, you can choose between different line types, setting the lty
argument from 0 to 6.
matplot(M, type = c("l"), lty = 1:6, col = "black", lwd = 3)
# Just to indicate the line types in the plot
j <- 0
invisible(sapply(seq(4, 40, by = 6),
function(i) {
j <<- j + 1
text(2, i, paste("lty =", j))}))
Type | Description |
---|---|
0 | Blank |
1 | Solid line (default) |
2 | Dashed line |
3 | Dotted line |
4 | Dotdash line |
5 | Longdash line |
6 | Twodash line |
Add text to plot in R
On the one hand, the mtext
function in R allows you to add text to all sides of the plot box. There are 12 combinations (3 on each side of the box, as left, center and right align). You just need to change the side
and adj
to obtain the combination you need.
On the other, the text
function allows you to add text or formulas inside the plot at some position setting the coordinates. In the following code block some examples are shown for both functions.
plot(x, y, main = "Main title", cex = 2, col = "blue")
#---------------
# mtext function
#---------------
# Bottom-center
mtext("Bottom text", side = 1)
# Left-center
mtext("Left text", side = 2)
# Top-center
mtext("Top text", side = 3)
# Right-center
mtext("Right text", side = 4)
# Bottom-left
mtext("Bottom-left text", side = 1, adj = 0)
# Top-right
mtext("Top-right text", side = 3, adj = 1)
# Top with separation
mtext("Top higher text", side = 3, line = 2.5)
#--------------
# Text function
#--------------
# Add text at coordinates (-2, 2)
text(-2, 2, "More text")
# Add formula at coordinates (3, -3)
text(3, -3, expression(frac(alpha[1], 4)))
Label points in R
In this section you will learn how to label data points in R. For that purpose, you can use the text
function, indicate the coordinates and the label of the data points in the labels
argument. With the pos
argument you can set the position of the label respect to the point, being 1 under, 2 left, 3 top and 4 right.
attach(USJudgeRatings)
# Create the plot
plot(FAMI, INTG,
main = "Familiarity with law vs Judicial integrity",
xlab = "Familiarity", ylab = "Integrity",
pch = 18, col = "blue")
# Plot the labels
text(FAMI, INTG,
labels = row.names(USJudgeRatings),
cex = 0.6, pos = 4, col = "red")
detach(USJudgeRatings)
You can also label individual data points if you index the elements of the text
function as follows:
attach(USJudgeRatings)
plot(FAMI, INTG,
main = "Familiarity with law vs Judicial integrity",
xlab = "Familiarity", ylab = "Integrity",
pch = 18, col = "blue")
# Select the index of the elements to be labelled
selected <- c(10, 15, 20)
# Index the elements with the vector
text(FAMI[selected], INTG[selected],
labels = row.names(USJudgeRatings)[selected],
cex = 0.6, pos = 4, col = "red")
detach(USJudgeRatings)
Change box type with bty argument
The bty
argument allows changing the type of box of the R graphs. There are several options, summarized in the following table:
Box type | Description |
---|---|
“o” | Entire box (default) |
“7” | Top and right |
“L” | Left and bottom |
“U” | Left, bottom and right |
“C” | Top, left and bottom |
“n” | No box |
The shape of the characters “7”, “L” and “U” represents the borders of the box they draw.
par(mfrow = c(2, 3))
plot(x, y, bty = "o", main = "Default")
plot(x, y, bty = "7", main = "bty = '7'")
plot(x, y, bty = "L", main = "bty = 'L'")
plot(x, y, bty = "U", main = "bty = 'U'")
plot(x, y, bty = "C", main = "bty = 'C'")
plot(x, y, bty = "n", main = "bty = 'n'")
par(mfrow = c(1, 1))
Note that in other plots, like boxplots, you will need to specify the bty
argument inside the par
function.
R plot legend
Finally, we will review how to add a legend to an R plot with the legend
function. You can set the coordinates where you want to add the legend or specify "top"
, "bottom"
, "topleft"
, "topright"
, "bottomleft"
or "bottomright"
. You can also specify lots of arguments like in the plot
function. As an example, you can change the bty in the R legend, the background color with the bg
argument, among others.
plot(x, y, pch = 19)
lines(-4:4, -4:4, lwd = 3, col = "red")
lines(-4:1, 0:5, lwd = 3, col = "green")
# Adding a legend
legend("bottomright", legend = c("red", "green"),
lwd = 3, col = c("red", "green"))
Take a look to the R legends article to learn more about how to add legends to the plots.