Skip to the content.

Base Plotting

Last Updated: 06, November, 2024 at 20:13

Notes

The base plotting system in R is somewhat dated (we’ll run into some limits below). But it is still a powerful way of creating plots programmatically.

Read in some data

This is the data source.

library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.1     ✔ tibble    3.2.1
## ✔ lubridate 1.9.3     ✔ tidyr     1.3.1
## ✔ purrr     1.0.2     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::lag()    masks stats::lag()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
body_data <- read_csv('data/body.csv')
## Rows: 507 Columns: 25
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (25): Biacromial, Biiliac, Bitrochanteric, ChestDepth, ChestDia, ElbowDi...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.
head(body_data)
## # A tibble: 6 × 25
##   Biacromial Biiliac Bitrochanteric ChestDepth ChestDia ElbowDia WristDia
##        <dbl>   <dbl>          <dbl>      <dbl>    <dbl>    <dbl>    <dbl>
## 1       42.9    26             31.5       17.7     28       13.1     10.4
## 2       43.7    28.5           33.5       16.9     30.8     14       11.8
## 3       40.1    28.2           33.3       20.9     31.7     13.9     10.9
## 4       44.3    29.9           34         18.4     28.2     13.9     11.2
## 5       42.5    29.9           34         21.5     29.4     15.2     11.6
## 6       43.3    27             31.5       19.6     31.3     14       11.5
## # ℹ 18 more variables: KneeDia <dbl>, AnkleDia <dbl>, Shoulder <dbl>,
## #   Chest <dbl>, Waist <dbl>, Navel <dbl>, Hip <dbl>, Thigh <dbl>, Bicep <dbl>,
## #   Forearm <dbl>, Knee <dbl>, Calf <dbl>, Ankle <dbl>, Wrist <dbl>, Age <dbl>,
## #   Weight <dbl>, Height <dbl>, Gender <dbl>
try(dev.off()) # Make sure all graphic parameters are reset
## null device 
##           1

Basic plot type: lines and scatter

Scatter plot

plot(body_data$KneeDia, body_data$Forearm)

Line plot

x <- 1:10
y <- runif(10) * x
plot(x, y, type= 'l')

plot(x, y, type= 'b')

Setting colors and markers

See here for a list of pch marker values. See here for a list of color names R knows out of the box.

x <- 1:10
y <- runif(10) * x
plot(x, y, type= 'b', pch=15, col ='red2')

R also knows about hex colors.

x <- 1:10
y <- runif(10) * x
plot(x, y, type= 'b', pch=15, col ='#47B04E')

Handy Dandy: adding an alpha channel to a color

my_red <- adjustcolor( "red2", alpha.f = 0.25)
plot(body_data$KneeDia, body_data$Forearm, pch=16, col=my_red)

Basic plot type: histogram

The hist() function has a number of interesting arguments:

hist(body_data$ChestDepth, freq = FALSE, main ='A normalized histogram')

Basic plot type: barchart

Some interesting arguments:

labels <- c('a', 'b', 'c', 'd', 'e', 'f')
values <- c(1, 2, 3, 1, 2, 3)
barplot(values, names.arg = labels)

Basic plot type: boxplot

body_data$AgeCat <- cut(body_data$Age, 10)
boxplot(body_data$Height ~ body_data$AgeCat)

Setting plot parameters

The function par() allows setting parameters for subsequent plots. Most importantly, you can set the subsequent plots’ margins and number of of subplots.

Setting the inner and the outer margins

You can find more information about inner and outer margins in R here.

par(oma=c(0,0,0,0))
x <- 1:10
y <- runif(10) * x
plot(x, y, type= 'l')

Plotting subplots

par(mfcol = c(1,2))
hist(body_data$ChestDepth, freq = FALSE, main ='A normalized histogram')
hist(body_data$Biiliac, freq = FALSE, main ='A normalized histogram')

try(dev.off())  # Make sure all graphic parameters are reset
## null device 
##           1

https://r-charts.com/base-r/combining-plots/

Changing text and font

Adding labels

  1. axis labels: xlab =, ylab =
  2. subtitle: sub =
  3. title: main =

Changing the font face

font face: font =

font family: family =

Scaling text sizes

  1. scaling all elements: cex =
  2. scaling axis labels: cex.lab =
  3. scaling subtitle: cex.sub =
  4. scaling tick mark labels: cex.axis =
  5. scaling title: cex.main =

Example

plot(x, y, type= 'b', family='serif', main='Some title', cex=1.25)

Adding stuff to existing plots

Adding points or lines

plot(body_data$KneeDia, body_data$Forearm)
points(c(18, 20, 22), c(22, 23, 24), type='b', col='red2')
points(c(18, 20, 22), c(23, 24, 25), col='blue2')

A limitation of R

This does cuts the range of the plot to the range of the first plotted data!

my_blue <- adjustcolor( "navyblue", alpha.f = 0.25)
my_red <- adjustcolor( "indianred4", alpha.f = 0.25)

males <- body_data[body_data$Gender==0,]
females <- body_data[body_data$Gender==1,]

plot(females$Height, females$Weight, pch=15, main='Some graph', col=my_blue)
points(males$Height, males$Weight, pch=15, main='Some graph', col=my_red)

This solves the problem. But it’s a bit dissapointing that R does not update the axes of the plots.

my_blue <- adjustcolor( "navyblue", alpha.f = 0.25)
my_red <- adjustcolor( "indianred4", alpha.f = 0.25)

xrange <- range(body_data$Height)
yrange <- range(body_data$Weight)

males <- body_data[body_data$Gender==0,]
females <- body_data[body_data$Gender==1,]

plot(females$Height, females$Weight, pch=15, main='Some graph', col=my_blue, xlim = xrange, ylim = yrange)
points(males$Height, males$Weight, pch=15, main='Some graph', col=my_red)

More bling

my_blue <- adjustcolor( "navyblue", alpha.f = 0.25)
my_red <- adjustcolor( "indianred4", alpha.f = 0.25)
my_orange <- adjustcolor( "orange", alpha.f = 0.5)

xrange <- range(body_data$Height)
yrange <- range(body_data$Weight)

males <- body_data[body_data$Gender==0,]
females <- body_data[body_data$Gender==1,]

plot(females$Height, females$Weight, pch=15, main='Some graph', col=my_blue, xlim = xrange, ylim = yrange, xlab='Height', ylab='Weight')
points(males$Height, males$Weight, pch=15, main='Some graph', col=my_red)

# Add a label to the graph
text(x=160, y=100, labels='A label', col="green2")
# Add a label to the graph
text(x=160, y=100, labels='A label', col="green2", font=3, family='serif')
# Add an arrow
arrows(x0=190, y0=100, x1=170,y1=60, length = 0.1, lwd=4, col=my_orange)

Adding legends

Adding legends can be done using the legend(). These are the main arguments to the function:

You can set the location using a keyword, i.e. x= “bottomright”, “bottom”, “bottomleft”, “left”, “topleft”, “top”, “topright”, “right” or “center”.

Apart from the location of the legend and the text to appear, you have to provide some parameters that set the legend’s markers.

my_blue <- adjustcolor( "navyblue", alpha.f = 0.25)
my_red <- adjustcolor( "indianred4", alpha.f = 0.25)
my_orange <- adjustcolor( "orange", alpha.f = 0.5)

xrange <- range(body_data$Height)
yrange <- range(body_data$Weight)

males <- body_data[body_data$Gender==0,]
females <- body_data[body_data$Gender==1,]

plot(females$Height, females$Weight, pch=15, main='Some graph', col=my_blue, xlim = xrange, ylim = yrange, xlab='Height', ylab='Weight')
points(males$Height, males$Weight, pch=15, main='Some graph', col=my_red)

# Add the legend - notice: we have to set the colors and markers for the legend manually
legend('bottomright', c('Men', 'Women'), col = c(my_red, my_blue), pch=15)

Exercises

Use these data:

body_data <- read_csv('data/body.csv')
## Rows: 507 Columns: 25
## ── Column specification ────────────────────────────────────────────────────────
## Delimiter: ","
## dbl (25): Biacromial, Biiliac, Bitrochanteric, ChestDepth, ChestDia, ElbowDi...
## 
## ℹ Use `spec()` to retrieve the full column specification for this data.
## ℹ Specify the column types or set `show_col_types = FALSE` to quiet this message.

More exercises

The internet is full of exercises on plotting in R (using the base plotting system). Here are two selected resources:

https://www.bioinformatics.babraham.ac.uk/training/Core_R_Plotting/Core%20R%20Plotting%20Exercises.pdf

This one uses the cars data we have already used in the course (I’ved added it to the data folder):

https://www.r-exercises.com/2016/09/23/advanced-base-graphics-exercises/