########################################################################## #R Code for figures and analysis in Webb, Vanden Berghe & O'Dor, 2010 ########################################################################## #Tom Webb, Feb 2010, t.j.webb@sheffield.ac.uk ########################################################################## #All analyses used R 2.9.2 running on Mac OSX 10.5.8 ########################################################################## #This is a standard R script file, which can be opened in R or an R-syntax #enabled script editor of choice by changing the file extension to .R ########################################################################## #Reading in and organising data #Set working dir to the directory you wish to work in, and in which you have the depth records dataset, e.g. setwd("/Users/tom/Documents/obis") #read in the data dat <- read.csv("recordcount.csv") #remove negative depths, which presumably indicate intertidal records, or errors: there are very few (n = 14 or so) depths dat <- dat[dat$bottomdepth >= 0,] dat <- dat[dat$sampledepth >= 0,] #when sample depth is deeper than bottom depth, set bottom depth to sample depth (i.e. assume that sample depth is accurate, and that it is a sample of the bottom) idx <- which(dat$sampledepth > dat$bottomdepth) dat$bottomdepth[idx] <- dat$sampledepth[idx] #assign each bottom depth to one of the 5 regions we use dat$reg <- cut(dat$bottomdepth, c(0,200,1000,4000,6000,11000), labels = c(0,200,1000,4000,6000), include.lowest = T) #Proportional areas of ocean of different depths from data described in Smith & Sandwell 1997, Science 277: 1956-1962, and available to download as an ASCII file from http://ibis.grdl.noaa.gov/cgi-bin/bathy/bathD.pl #Read in the global data glob.depths <- read.table("global_map.xyz.sav", sep = "\t") #add column names names(glob.depths) <- c("x", "y", "depth") #restrict to negative depths (i.e., not terrestrial altitude) glob.d2 <- glob.depths[glob.depths$depth <= 0,] #make depths positive glob.d2$d <- -1*glob.d2$depth #split into the depth zone categories glob.d2$d.cat <- cut(glob.d2$d, breaks = c(0, 200, 1000, 4000, 6000, 11000), include.lowest = T, labels = F) #and get percentages of ocean at different depths: #So, p.area becomes: p.area <- round(100*table(glob.d2$d.cat) / dim(glob.d2)[1], 1) #And for cumulative percentages: p.area.cum <- as.vector(c(0, cumsum(p.area))) ##################################################################### #Code for figure 1 #First, a simple plot of total number of records against bottom depth recs.x.dep.fig <- function(){ #Set a few basic graphical parameters par(bg = "white", mar = c(5,6.5,1,1), mgp = c(3.75,1,0)) #Plot the raw data as pale grey symbols plot(I(-1*depth) ~ log10(no.recs), data = rec.tots.df, xaxt = "n", yaxt = "n", ylab = "depth (m)", xlab = "number of records", las = 1, col = "grey", cex.lab = 1.5) #Add axes with prettier labels than the default axis(side = 2, at = seq(-11000, 0, by = 1000), labels = seq(11000, 0, by = -1000), las = 1) axis(side = 1, at = 0:5, labels = c(expression(10^0), expression(10^1), expression(10^2), expression(10^3), expression(10^4), expression(10^5)), las = 1) #Add lines to split the ocean into the depth zones we use abline(h = c(-200,-1000,-4000,-6000), lty = 2) #Add a lowess fit. NB: the lowess sensibly fits records as a function of depth, even though the plot has the axes the other way around fm <- loess(log10(no.recs) ~ depth, data = rec.tots.df, span = 0.1) lines(fm$fitted, -1*rec.tots.df$depth, lwd = 4) } #Next, the proportion records vs. proportion area figure p.recs.x.p.area.fig <- function(newplot = F){ #Create a new plot region if required (Windows users - replace 'quartz' with an appropriate graphics device, e.g. 'windows') if(newplot == T){ quartz(width = 8) } #Set graphical parameters par(bg = "white", mar = c(4.2,5,1,8.2), mgp = c(3,1,0)) #Create a pretty palette of colours my.pal = rainbow(5, start = 0, end = 2/3) #get proportion of records in each region precs.x.reg <- tapply(dat$recordcount, dat$reg, sum) / sum(dat$recordcount) precs <- as.vector(precs.x.reg) #proportion of ocean surface area in each region is p.area - see above parea <- as.vector(p.area / 100) #draw the plot plot(precs ~ parea, xlab = "proportion of ocean area", ylab = "proportion of records", las = 1, pch = 21, bg = my.pal, cex = 2, xlim = c(0,0.55), ylim = c(0,0.55), cex.lab = 1.5) #add 1:1 line abline(0,1, lty = 3, lwd = 3) #add legend legend(0.57,0.59, legend = c("0-200m", "200-1000m", "1000-4000m", "4000-6000m", ">6000m"), pch = 21, pt.bg = my.pal, bg = "white", cex = 1.2, xpd = T, bty = "n") } #Combine both of the above into figure 1 figure1 <- function(){ #Set up the plot area quartz(height = 4, width = 10) #Give more space to panel B than A layout(matrix(c(1,2), byrow = T, ncol = 2), widths = c(8,10)) #Call panel A recs.x.dep.fig() #Add label text(-1.75, 400, "A", cex = 2, xpd = T) #Call panel B p.recs.x.p.area.fig() #Add label text(-0.12, 0.57, "B", cex = 2, xpd = T) } #To produce the figure figure1() ##################################################################### #Code for figure 2 #Fig 2 requires a finer division of sample and bottom depths #This creates categorical variables for both sample and bottom depth. Here, depth increases in 50m bands up to 200m, in 100m bands from 200-1000m, in 200m bands from 1000-6000m, and 1000m bands thereafter (these are 'sensible' divisions, based on the number of records from different depths) #bottom depth categories dat$bd.cat50 <- cut(dat$bottomdepth, breaks = c( seq(0,200, by = 50), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), labels = c( seq(50,200, by = 50), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), include.lowest = T) #next, sample depth categories dat$sd.cat50 <- cut(dat$sampledepth, breaks = c( seq(0,200, by = 50), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), labels = c( seq(50,200, by = 50), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), include.lowest = T) #Now, tablulate summed record counts by sample depth category (rows) and bottom depth category (columns) recs.sum50 <- tapply(dat$recordcount, list(dat$sd.cat50, dat$bd.cat50), sum) #For the figure to work properly, need to flip the matrices vertically (which has the effect of making depth 'negative', so that greater depths appear lower down on the figure) recs.sum50 <- recs.sum50[nrow(recs.sum50):1,] #In order to get the figure so that it is scaled by the relative area of the ocean at different depths, a new bottom depth vector is required. #First, determine how many division in each depth zone: #there are 42 cols / rows in recs.sum, which are split between the depth categories as follows: n.per.cat50 <- c(4, 8, 15, 10, 5) bd.cats50 <- numeric() for(i in 1:5){ bd.cats50 <- c(bd.cats50, seq(p.area.cum[i], p.area.cum[i+1], length.out = n.per.cat50[i] + 1)[1:n.per.cat50[i]] ) } bd.cats50 <- c(bd.cats50, 100) #sample depth categories are simply the column headings (same as categories used to tabulate the data) sd.cats50 <- sort(-1 * c(seq(0,200, by = 50), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000))) #To standardise the number of records in each 'cell' of the recs.sum50 matrix by the volume of water represented by that cell, #First, get dimensions on the two axes diffs.sd <- matrix(diff(sd.cats50)) diffs.bd <- matrix(diff(bd.cats50), ncol = 42) #matrix of cell areas area.mat <- diffs.sd%*%diffs.bd #records divided by cell areas rec.by.area.mat <- recs.sum50 / area.mat #Because the 'surface area' axis is already an area, 'area' in this matrix is effectively volume #The continental shelf and slope figure uses a finer (10m) resolution of shallow water #This requires a new set of sample and bottom depth categories dat$bd.cat10 <- cut(dat$bottomdepth, breaks = c( seq(0,200, by = 10), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), labels = c( seq(10,200, by = 10), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), include.lowest = T) #next, sample depth categories dat$sd.cat10 <- cut(dat$sampledepth, breaks = c( seq(0,200, by = 10), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), labels = c( seq(10,200, by = 10), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000) ), include.lowest = T) #Now, tablulate summed record counts by sample depth category (rows) and bottom depth category (columns) recs.sum10 <- tapply(dat$recordcount, list(dat$sd.cat10, dat$bd.cat10), sum) #Flip the matrix vertically (which has the effect of making depth 'negative', so that greater depths appear lower down on the figure) recs.sum10 <- recs.sum10[nrow(recs.sum10):1,] #In order to get the figure so that it is scaled by the relative area of the ocean at different depths, a new bottom depth vector is required. #First, get the number of columns in each depth zone: n.per.cat10 <- c(20,8,15,10,5) #Then create the bottom depth categories bd.cats10 <- numeric() for(i in 1:5){ bd.cats10 <- c(bd.cats10, seq(p.area.cum[i], p.area.cum[i+1], length.out = n.per.cat[i] + 1)[1:n.per.cat[i]] ) } bd.cats10 <- c(bd.cats10, 100) #sample depth categories are simply the column headings (same as categories used to tabulate the data) sd.cats10 <- sort(-1 * c(seq(0,200, by = 10), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000))) #Standardise the continental shelf/slope data by volume, as before diffs.sd.cs <- matrix(diff(sd.cats10[31:59])) diffs.bd.cs <- matrix(diff(bd.cats10[1:29]), ncol = 28) area.mat.cs <- diffs.sd.cs %*% diffs.bd.cs rec.by.area.cs <- recs.sum.cs / area.mat.cs #The first stage of fig 2 is to set up the representation of the ocean, which uses this function setup.plot50 <- function(newplot = F, addlines = F, deep.pelagic = F, blue.col = "cornflowerblue", bottom.lwd = 0.5, do.bottom = T, x = bd.cats50, y = sd.cats50, add.axis = T){ #Create a new plot region if required if(newplot == T){ quartz() #set appropriate margins par(mar = c(1,6,2,2), bg = "white") } #To colour the ocean blue, first create a 'dummy' matrix, with 1 for the area to colour, NA otherwise recsum.dummy <- recs.sum50 recsum.dummy[!is.na(recsum.dummy)] <- 1 for(i in 9:1){ recsum.dummy[,43-i] <- c(rep(NA, i-1), rep(1, 43-i)) } #This actually plots the ocean image(x, y, t(recsum.dummy), col = blue.col, yaxt = "n", xaxt = "n", ylab = "", xlab = "", bty = "n") #Various axes, lines etc. can be added if required if(add.axis == T){ #add an axis at the top, splitting the ocean into different depth zones #this involves a separate call for the axis line and the tick marks axis(side = 3, at = p.area.cum, xpd = T, lwd = bottom.lwd, lwd.ticks = 0, labels = F) axis(side = 3, at = p.area.cum[1:5], cex.axis = 1, xpd = T, lwd.ticks = bottom.lwd, lwd = 0, labels = F, tck = -.02) #depths for axis, on simple scale d.raw <- seq(-11000, 0, by = 1000) #add depth axis to the left hand side of the plot axis(side = 2, at = d.raw, labels = -1*d.raw, las = 1, lwd = bottom.lwd) text(-17, -5500, "depth (m)", xpd = T, cex = 1.5, srt = 90) #finally, add labels to indicate the different depth zones text.pos <- p.area.cum[1:5] + diff(p.area.cum)/2 text.pos[5] <- 101 text(text.pos, rep(0, 5), c("A","B","C","D","E"), pos = 3, xpd = T) } } #This actually produces the plot. It requires that you have installed the 'shape' package from CRAN, which is used for the colour palette figure2 <- function(rec.dat = rec.by.area.mat, add.cont.shelf = T, cs.rec.dat = rec.by.area.cs, min.rec = NULL, max.rec = NULL, v.scale = F){ #ensure shape package is loaded, for creating palette require(shape) #A couple of internal functions, first to add a volume scale, then to add the continental slope inset vol.scale <- function(){ #add an approximate volume scale onto the plot, based a global ocean surface area of 361M km^3 #this gives the volume of one of the 'cells' in the deep sea, which is 200m in depth and 4.86% of the global #ocean area. So the area is 0.0486*(361 * 10^6)km^2, and to get volume multiply by 0.2km, giving 3508920km^3 x.dim <- diff(bd.cats50)[cumsum(n.per.cat50)[4]] polygon( x = c(22, 22+x.dim, 22+x.dim, 22, 22), y = c(-3600, -3600, -3800, -3800, -3600), col = "cornflowerblue" ) text(22 + 0.5*x.dim, -3600, expression(paste("c.", 3.5, " x ", 10^6, "k", m^3)), pos = 3, cex = 0.8) } cont.slope.fig <- function(rec.dat.cs = rec.by.area.cs, pal = NULL, min.rec = NULL, max.rec = NULL){ #Add the inset figure of the continental shelf and slope #Note, this uses a finer resolution of depths for shallow water (10m) #create the plot region par(fig = c(0.2,0.5,0.05,0.35), new = T) #Fill with blue recsum.dummy <- rec.dat.cs recsum.dummy[!is.na(recsum.dummy)] <- 1 #fill in image(bd.cats10[1:29], sd.cats10[31:59], t(recsum.dummy), col = "cornflowerblue", yaxt = "n", xaxt = "n", ylab = "", xlab = "", bty = "n", cex.main = 1, bg = "white") #add the records if(is.null(max.rec)){ min.rec = min(log10(rec.dat.cs), na.rm = T) max.rec = max(log10(rec.dat.cs), na.rm = T) } image(bd.cats10[1:29], sd.cats10[31:59], t(log10(rec.dat.cs)), col = pal, ylab = "", xlab = "", bty = "n", add = T, yaxt = "n", xaxt = "n", zlim = c(min.rec, max.rec)) #depths for axis, on simple scale d.raw <- seq(-1000,0, by = 100) #add axis axis(side = 4, at = d.raw, labels = F, las = 1, lwd = 0.5) axis(side = 4, at = d.raw[seq(1, 11, by = 2)], labels = -1*d.raw[seq(1, 11, by = 2)], tck = F, las = 1, lwd = 0.5) #this adds the bottom profile to the figure x <- rep(bd.cats10[1:29], each = 2)[-1] x <- x[-length(x)] y <- rep(sort(sd.cats10[31:59], decreasing = T)[-1], each = 2) polygon(c(x, 11.9,0,0), c(y, -1000, -1000, -10), lwd = 0.5, col = "white") } #create the colour palette, and set up the background pal <- intpalette(c("cornflowerblue", "lightblue1", "yellow", "orangered", "red"), numcol = 46) #create background plot setup.plot50(newplot = T, blue.col = "cornflowerblue", bottom.lwd = 0.75, do.bottom = F) #fill in with log(record numbers); the maximum number of records is derived from the data, unless specified in the 'max.rec' argument. #The purpose of specifying is to maintain the same colour scale on the main plot and the continental shelf inset, if this is to be produced. #NB - if max.rec IS specified, you MUST also specify min.rec. if(is.null(max.rec)){ image(bd.cats50, sd.cats50, t(log10(rec.dat)), col = pal, ylab = "", xlab = "", bty = "n", add = T) } else { image(bd.cats50, sd.cats50, t(log10(rec.dat)), col = pal, ylab = "", xlab = "", bty = "n", add = T, zlim = c(min.rec, max.rec)) } #add the sea bottom profile x <- rep(bd.cats50, each = 2)[-1] x <- x[-length(x)] y <- rep(sort(sd.cats50, decreasing = T)[-1], each = 2) polygon(c(x, 100,0,0), c(y, -11000, -11000, -50), lwd = 0.75) #add vertical divisions between depth zones abline(v = p.area.cum[1:5], lwd = 0.5, xpd = F) #The final division is slightly different for clarity segments(100.05, 100, 100.05, -11000, lwd = 0.5, xpd = T) #add horizontal divisions between depth zones abline(h = c(-200, -1000, -4000, -6000), lwd = 0.5, xpd = F) #add volume scale if required if(v.scale == T){vol.scale()} #add a scale of record numbers and (if add.cont.shelf has been specified as TRUE) the continental shelf inset #first, add a title for the scale(easier to do this now) text(75, -6900, "number of records", cex = 1.2) #then, set up some space for the continental shelf inset, and a title, if required if(add.cont.shelf == T){ polygon(c(5,45,45,5,5), c(-6500,-6500,-10800,-10800,-6500), col = "white", border = NA) text(25.05, -6900, "continental shelf & slope", cex = 1.2) } #Set up a new plot region for the scale par(fig = c(0.73,0.83,0.05,0.35), new = T) par(mar = c(0.5,1,1,0.5)) #and draw the scale as a new image plot - set the scale using the specified max.rec, or a sensible value from the data if(is.null(max.rec)){ max.rec <- round(max(log10(rec.dat), na.rm = T), 2) + 0.01 } #Some code adapted from http://www.phaget4.org/R/image_matrix.html ColorLevels <- seq(from = -1*max.rec, to = 0, length = length(pal)) ColorRamp <- pal[length(pal):1] image(1, ColorLevels, matrix(data=ColorLevels, ncol=length(ColorLevels),nrow=1), col=ColorRamp, xlab="",ylab="", xaxt="n", las = 1, yaxt = "n") #add an axis with log10 scale #First, get an integer value for maximum max.rec.int <- round(max.rec) #Then add the axis. #First, create pretty axis labels (a sequence of 10s with superscripts from 0 to max.rec.int) ax.lab <- rep(expression(10^0), (max.rec.int + 1)) for(i in 2:(max.rec.int + 1)){ax.lab[[i]][3] <- i - 1} #now add the axis axis(side = 2, at = -1*max.rec.int:0, labels = ax.lab, las = 1) #Finally, add the continental slope figure if required if(add.cont.shelf == T){cont.slope.fig(rec.dat.cs = cs.rec.dat, pal = pal, min.rec = min.rec, max.rec = max.rec)} } #To produce the figure: figure2(rec.dat = rec.by.area.mat, cs.rec.dat = rec.by.area.cs, max.rec = max(log10(rec.by.area.cs), na.rm = T), min.rec = min(log10(rec.by.area.mat), na.rm = T), v.scale = T) ##################################################################### #Code for figure 3 #For this figure, the area-standardised records need to be standardised by column (i.e. so that each column sums to 1) rec.by.area.stand <- scale(rec.by.vol.mat, center = F, scale = colSums(rec.by.vol.mat, na.rm = T)) #This figure sacrifices the area-for-volume equivalence of fig2, in favour of increased clarity in some regions #This requires a new vector of bottom depths, derived by splitting the area of the ocean more equally #specifically, the width of each region on the x-axis is the square root of its proportional area p.area.eq <- c(0, cumsum(sqrt(p.area))) bd.cats.eq50 <- numeric() for(i in 1:5){ bd.cats.eq50 <- c(bd.cats.eq50, seq(p.area.eq[i], p.area.eq[i+1], length.out = n.per.cat50[i] + 1)[1:n.per.cat50[i]] ) } bd.cats.eq50 <- c(bd.cats.eq50, sum(sqrt(p.area))) #Likewsise, depth (the y-axis) is transformed to stretch out shallower depths somewhat. The 2/3 power does this nicely sd.cats.trans50 <- -1 * (-1*sd.cats50)^(2/3) #Code for the figure. #NB the argument 'min.recs' allows you to specify the minimum proportion of records within a column that a cell must contain in order to be coloured, although in the ms we use all records figure3 <- function(rec.dat = recsum.stand50, min.recs = 0.001, newplot = T){ #create the background plot setup.plot50(blue.col = "cornflowerblue", do.bottom = F, x = bd.cats.eq50, y = sd.cats.trans50, add.axis = F, newplot = newplot) #create a suitable palette require(shape) pal <- intpalette(c("lightblue1", "yellow", "orangered", "red"), numcol = 46) #fill the plot with p(records) image(bd.cats.eq50, sd.cats.trans50, t(rec.dat), col = pal, yaxt = "n", xaxt = "n", ylab = "", xlab = "", bty = "n", add = T, zlim = c(min.recs, 1)) #add axes, etc axis(side = 3, at = p.area.eq, cex.axis = 1, xpd = T, lwd = .75, labels = F, tck = -.02) #depths for axis, on transformed scale d.seq <- c(0,200,seq(1000, 11000, by = 1000)) d.seq.trans <- -1 * (d.seq)^.67 #add depth axis axis(side = 2, at = d.seq.trans, labels = c(0, 200, seq(1000, 11000, by = 1000)), las = 1, lwd = 0.75) text(-3, -250, "depth (m)", xpd = T, cex = 1.5, srt = 90) #add vertical and horizontal divisions between depth zones abline(v = p.area.eq[2:5], lwd = 0.5, xpd = F) segments(p.area.eq[6], d.seq.trans[1], p.area.eq[6], d.seq.trans[length(d.seq.trans)], lwd = 0.75, xpd = T) abline(h = d.seq.trans[c(2,3,6,8)], lwd = 0.5) #add bottom profile x <- rep(bd.cats.eq50, each = 2)[-1] x <- x[-length(x)] y <- rep(sort(sd.cats.trans50, decreasing = T)[-1], each = 2) polygon(c(x, max(bd.cats.eq50),0,0), c(y, min(sd.cats.trans50), min(sd.cats.trans50), sd.cats.trans50[42]), lwd = 0.75) #add labels to indicate the different depth zones text.pos <- p.area.eq[1:5] + diff(p.area.eq)/2 text(text.pos, rep(0, 5), c("A","B","C","D","E"), pos = 3, xpd = T) #Add the colour scale #first, blank out some space polygon(x = c(0.01, 6, 6, 0.01, 0.01), y = c(-475, -475, -265, -265, -509), border = NA, col = "white") #then add a title text(p.area.eq[2], d.seq.trans[7] + 10, "prop. records", cex = 1.2) #then, set up the new plot par(fig = c(0.22,0.32,0.1,0.4), new = T) par(mar = c(0.5,0.5,1,1)) #and draw it ColorLevels <- seq(from = -1, to = 0, length = length(pal) + 1) ColorRamp <- c(pal[length(pal):1], "#6495ED") image(1, ColorLevels, matrix(data=ColorLevels, ncol=length(ColorLevels),nrow=1), col=ColorRamp, xlab="",ylab="", xaxt="n", las = 1, yaxt = "n") #and add an axis from 0 to 1 axis(side = 4, at = seq(-1,0, by = 0.2), labels = c("1.0", seq(0.8, 0.2, by = -0.2), "0.0"), las = 1) } #To produce the plot fig3.50(rec.dat = rec.by.area.stand, min.recs = 0.0, newplot = T) ##################################################################### #Code for figure 4 #This requires calculation of the proportion of records from midwater #For continental shelf and slope, use top 10m for surface, bottom stratum for bottom cs.surface <- rec.by.area.cs[28,] cs.bottom <- numeric() for(i in 1:28){cs.bottom[i] <- rec.by.area.cs[29-i, i]} #this is the total number of records in each stratum cs.tot <- colSums(rec.by.area.cs, na.rm = T) #so, midwater proportion cs.midwater <- (cs.tot - (cs.surface + cs.bottom))/cs.tot #exclude first 2 depths (where there is no midwater, by our definition) cs.midwater <- cs.midwater[-c(1,2)] #For deeper seas, use top 100m for surface, bottom stratum for bottom deep.surface <- colSums(rec.by.area.mat[41:42,13:42], na.rm = T) deep.bottom <- numeric() for(i in 13:42){deep.bottom[i-12] <- rec.by.area.mat[43-i, i]} #Total records in each column deep.tot <- colSums(rec.by.area.mat[,13:42], na.rm = T) #so, midwater propotion deep.midwater <- (deep.tot - (deep.surface + deep.bottom))/deep.tot #get midpoint of depth for each column d <- c(seq(0,200, by = 10), seq(300, 1000, by = 100), seq(1200, 6000, by = 200), seq(7000, 11000, by = 1000)) d <- d[1:58] + 0.5*diff(d) #combine all data into a data frame midwater.p <- data.frame(d = d[-c(1,2)], zone = rep(c("A", "B", "C", "D", "E"), c(18,8,15,10,5)), p.mid = c(as.vector(cs.midwater), as.vector(deep.midwater))) #Here's the code to produce the figure figure4 <- function(){ #Set up the plot quartz() par(mar = c(7.5,4,1,1)) #Create the plot boxplot(p.mid ~ zone, data = midwater.p, las = 1, xlab = "", ylab = "Proportion of midwater records", xaxt = "n", range = 0, outline = F, whisklty = 1, ylim = c(0, 0.5)) #add x labels text(1:5, rep(-0.03, 5), c("0-200m", "200-1000m", "1000-4000m", "4000-6000m", ">6000m"), srt = 60, xpd = T, adj = 1, cex = 1.15) } #To call the figure figure4() #This is the correlation test, of proportion of midwater records against bottom depth cor.test(midwater.p$d, midwater.p$p.mid, method = "s") #####################################################################