Base Plotting
Last Updated: 06, November, 2024 at 20:13
- Notes
- Read in some data
- Basic plot type: lines and scatter
- Basic plot type: histogram
- Basic plot type: barchart
- Basic plot type: boxplot
- Adding stuff to existing plots
- Adding legends
- Exercises
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:
- main
- xlab, ylab
- freq
hist(body_data$ChestDepth, freq = FALSE, main ='A normalized histogram')
Basic plot type: barchart
Some interesting arguments:
- names.arg
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
- mfrow and mfcol plot orders:
https://r-charts.com/base-r/combining-plots/
Changing text and font
Adding labels
- axis labels:
xlab =
,ylab =
- subtitle:
sub =
- title:
main =
Changing the font face
font face: font =
- values: 1 (plain), 2 (bold), 3 (italic), or 4 (bold italic)
font family: family =
- “serif”, “sans”, or “mono”
Scaling text sizes
- scaling all elements:
cex =
- scaling axis labels:
cex.lab =
- scaling subtitle:
cex.sub =
- scaling tick mark labels:
cex.axis =
- 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:
- x and y : the x and y co-ordinates to be used to position the legend
- legend : the text of the legend
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.
-
Create a histogram of people’s height, split out by gender. Overlay the histogram for women and men (use an alpha setting to make both of them visible). Make sure the histogram shows all data and is not cut off.
-
Plot a bar chart of people’s height. Use 10-year age bins on the x-axis.
-
Create a cumulative histogram of people’s height (or any other variable).
More exercises
The internet is full of exercises on plotting in R (using the base plotting system). Here are two selected resources:
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/