2. Comparison of chlorophyll data from different sensors

This tutorial will showcase the use of the rerddap package, which was developed to make it easier to interact with ERDDAP servers from R. More information about the package can be found here: https://cran.r-project.org/web/packages/rerddap/index.html and here: https://cran.r-project.org/web/packages/rerddap/vignettes/Using_rerddap.html

As an example, we are going to plot time-series of mean chlorophyll a concentration from various sensors from 1997 to 2018 to look at the periods of overlap. We are going to download data from Seawifs (1997-2010), MODIS (2002-present) and VIIRS (2012-present) and compare it to the ESA-CCI data which combines all 3 sensors into a homogeneous time-series.

Load packages: require(lubridate) require(plyr) library(rerddap) library(ncdf4)

First we define the longitude-latitude boundaries of the box:

xcoord<-c(198,208) ycoord<-c(15,25)

Next we define the URL of the ERDDAP we will be using:

ERDDAP_Node="https://oceanwatch.pifsc.noaa.gov/erddap/"

Get monthly seawifs data, which starts in 1997.

Go to ERDDAP to find the name of the dataset for monthly SeaWIFS data: sw_chla_monthly_2018_0

You should always examine the dataset in ERDDAP to check the date range, names of the variables and dataset ID, to make sure your griddap calls are correct: https://oceanwatch.pifsc.noaa.gov/erddap/griddap/sw_chla_monthly_2018_0.html

First we need to know what our variable is called:

dataInfo <- rerddap::info('sw_chla_monthly_2018_0', url=ERDDAP_Node) var=dataInfo$variable$variable_name var

[1] "chlor_a" "palette"

We are interested in the chlor_a variable, which contains the values of chlorophyll-a concentration. This is var[1].

griddap is a function from the rerddap package. It grabs the data from ERDDAP based on the parameters we give it.

We are grabbing a lot of data so all the griddap commands might take a while.

sw <- griddap(url=ERDDAP_Node, 'sw_chla_monthly_2018_0', time = c('1997-12-01', '2010-12-01'), latitude = ycoord, longitude = xcoord, fields = var[1] )

Spatially average all the data within the box

swAVG <- ddply( sw$data, .(time), function(x) mean(x$chlor_a, na.rm =TRUE) )

Get monthly MODIS data, which starts in 2002.

dataInfo <- rerddap::info('aqua_chla_monthly_2018_0', url=ERDDAP_Node) var=dataInfo$variable$variable_name MOD <- griddap(url=ERDDAP_Node, 'aqua_chla_monthly_2018_0', time = c('2002-07-16', '2018-12-16'), latitude = ycoord, longitude = xcoord, fields = var[1])

Spatially average all the data within the box:

MODAVG <- ddply( MOD$data, .(time), function(x) mean(x$chlor_a, na.rm =TRUE) )

Get monthly VIIRS data, which starts in 2012.

dataInfo <- rerddap::info('noaa_snpp_chla_monthly', url=ERDDAP_Node) var=dataInfo$variable$variable_name VIIRS <- griddap(url=ERDDAP_Node, 'noaa_snpp_chla_monthly', time = c('2012-01-02', '2018-12-01'), latitude = ycoord, longitude = xcoord, fields = var)

Spatially average all the data within the box:

VIIRSAVG <- ddply( VIIRS$data, .(time), function(x) mean(x$chlor_a, na.rm =TRUE) )

Get OC-CCI data (September 1997 to Dec 2018)

dataInfo <- rerddap::info('esa-cci-chla-monthly-v4-2', url=ERDDAP_Node) var=dataInfo$variable$variable_name CCI <- griddap(url=ERDDAP_Node, 'esa-cci-chla-monthly-v4-2', time = c('1997-09-04', '2018-12-01'), latitude = ycoord, longitude = xcoord, fields = var[1] )

Spatially average all the data within the box:

CCIAVG <- ddply( CCI$data, .(time), function(x) mean(x$chlor_a, na.rm =TRUE) )

Plot time series result

plot(as.Date(swAVG$time), swAVG$V1, type='l', col=2,lwd=2, xlab="", xlim=as.Date(c("1997-12-01","2018-12-01")), ylim=c(0.035,0.10), ylab="CHL") axis(2) points(as.Date(swAVG$time), swAVG$V1,pch=20,col=2) lines(as.Date(MODAVG$time), MODAVG$V1, col=4, lwd=2) points(as.Date(MODAVG$time), MODAVG$V1,pch=20,col=4) lines(as.Date(VIIRSAVG$time), VIIRSAVG$V1, col=3, lwd=2) points(as.Date(VIIRSAVG$time), VIIRSAVG$V1,pch=20,col=3) legend('bottomleft',legend=c('sw','mod','viirs'),cex=0.6,col=c(2,4,3),lwd=2)

You can see that the values of chl-a concentration don't match between sensors.

Make another plot with CCI as well to compare

plot(as.Date(swAVG$time), swAVG$V1, type='n', col=2,lwd=2, xlab="", xlim=as.Date(c("1997-12-01","2018-12-01")), ylim=c(0.035,0.10), ylab="CHL") axis(2) points(as.Date(swAVG$time), swAVG$V1,pch=20,col=2) points(as.Date(MODAVG$time), MODAVG$V1,pch=20,col=4) points(as.Date(VIIRSAVG$time), VIIRSAVG$V1,pch=20,col=3) lines(as.Date(CCIAVG$time),CCIAVG$V1) legend('bottomleft',legend=c('sw','mod','viirs','cci'), cex=0.6,col=c(2,4,3,1),pch=c(20,20,20,NA),lty=c(NA,NA,NA,1),lwd=2)

Last updated