Hey,

I’ve decided to do a quick post on how to add a convex hull to a x-y scatterplot in R. This a handy way of visualizing data if you have multiple dataset on one plot. If you google “convex hull in R stat”, you will find many existing packages that have functions to do this, but as always, I like to use base functions as much as possible to do the dirty work, and resort to contributed packages as needed. Lets go!

First, I’ll introduce the function I created to make the convex hull, Plot_ConvexHull.R. We utilize the base function “chull()”, which takes the x,y coordinates of your data and outputs a vector (hpts variable) of integers that indicate the points in your dataset that comprise the convex hull around your data (see ?chull for more details). You will see that I append hpts[1] to the end of the hpts so that the convex hull creates a closed circle around the data points. Finally I use the base function lines to draw the convex hull using the x,y coordinates stored in hpts. Pretty simple:

### Plotting function to plot convex hulls
### Filename: Plot_ConvexHull.R
### Notes:
############################################################################
# INPUTS:
# xcoords: x-coordinates of point data
# ycoords: y-coordinates of point data
# lcolor: line color
# OUTPUTS:
# convex hull around data points in a particular color (specified by lcolor)
# FUNCTION:
Plot_ConvexHull<-function(xcoord, ycoord, lcolor){
hpts <- chull(x = xcoord, y = ycoord)
hpts <- c(hpts, hpts[1])
lines(xcoord[hpts], ycoord[hpts], col = lcolor)
}
# END OF FUNCTION

Now, let’s do a simple example using Plot_ConvexHull.R:

#Tell R where your function is located (this will be unique to your file directory)
source("/home/location_of_R_code/Plot_ConvexHull.R")
# Create 3 sets of random data to plot convex hull around
x1 <- rnorm(100, 0.8, 0.3)
y1 <- rnorm(100, 0.8, 0.3)
x2 <- rnorm(100, 0.2, 0.3)
y2 <- rnorm(100, 0.2, 0.3)
x3 <- rnorm(100, 1.4, 0.3)
y3 <- rnorm(100, 1.4, 0.3)
# get max and min of all x and y data for nice plotting
xrange <- range(c(x1, x2, x3))
yrange <- range(c(y1, y2, y3))
# Plot it up!
par(tck = 0.02, mgp = c(1.7, 0.3, 0))
plot(x1, y1, type = "p", pch = 1, col = "black", xlim = c(xrange), ylim = c(yrange))
Plot_ConvexHull(xcoord = x1, ycoord = y1, lcolor = "black")
points(x2, y2, type = "p", pch = 1, col = "green")
Plot_ConvexHull(xcoord = x2, ycoord = y2, lcolor = "green")
points(x3, y3, type = "p", pch = 1, col = "magenta")
Plot_ConvexHull(xcoord = x3, ycoord = y3, lcolor = "magenta")

Pretty nice:

Oh yeah, happy new year!!!