#' Plot maps for esd objects
#'
#' Make map of geophysical data. These plot functions are S3 methods for esd
#' objects.
#'
#' @aliases map map.default map.matrix map.data.frame map.station
#' map.stationmeta map.stationsummary map.comb map.eof map.ds
#' map.field map.corfield map.cca map.events map.mvr map.pca map.array
#' map.trend map.mvcomb lonlatprojection rotM map2sphere
#' @seealso map.trajectory vec map.dsensemble
#'
#' @param x the object to be plotted; in \code{rotM}, x holds a vector of
#' x-coordinates.
#' @param FUN The function to be applied on x before mapping (e.g. \code{mean})
#' @param colbar The colour scales defined through \code{colscal}. Users can
#' specify the colour `pal'*ette (`pal'), the number of breaks (`n'), values of
#' `breaks', and the position of the color bar from the main plot (`pos'). The
#' `rev' argument, will produce a reversed color bar if set to TRUE. The other
#' arguments (`type',`h' and `v') are more specific to \code{col.bar} and are
#' used only if argument `fancy' is set to TRUE (not yet finished). \code{colbar=NULL}
#' is used if the colourbar is not to be shown. Also use \code{colbar=NULL} to present several
#' maps in one figure (e.g. with \code{par(mfcol=c(2,2))}).
#' @param lab \code{'default'} to show a lable saying what variable (unit) and time period.
#' \code{'simple'} to just use \code{varid(x)}, and \code{'unit'} to show variable and unit.
#' Other strings will be used as the label for the plot and \code{NULL} shows no label.
#'
#' @param it see \code{\link{subset}}
#' @param is see \code{\link{subset}}
#' @param new TRUE: create a new graphic device.
#' @param projection Projections: c("lonlat","sphere","np","sp") - the latter
#' gives stereographic views from the North and south poles. Other types of projections
#' are also possible based on a wrapper function for \code{oce::mapPlot}
#' (e.g. \code{projection="+proj=moll"}) - see the details provided for
#' \code{oce::mapPlot} for available projections.
#' @param xlim see \code{\link{plot}} - only used for 'lonlat' and 'sphere'
#' projections. Default \code{xlim=NULL} is the same as \code{c(-1,+1)} and refers to coordinates
#' on a unit sphere (radius = 1). If plotting should be limited to a range of longitudes and latitudes
#' then \code{subset(.)} can be used prior to \code{map}.
#' @param ylim see \code{\link{plot}} - only used for 'lonlat' and 'sphere'
#' projections. See \code{xlim}.
#' @param n The number of colour breaks in the color bar
#' @param breaks graphics setting - see \code{\link{image}}
#' @param type graphics setting - colour shading ('fill'), contour ('contour') or both c('fill', 'contour').
#' The default is both 'fill' and 'contour'
#' @param gridlines Only for the lon-lat projection
#' @param lonR Only for the spherical projection used by \code{map2sphere} to change viewing angle
#' @param latR Only for the spherical projection used by \code{map2sphere} to change viewing angle
#' @param axiR Only for the spherical projection used by \code{map2sphere} to change viewing angle
#' @param style Only for the spherical projection used by \code{map2sphere} to apply night shade effect. c('plain','night')
#' @param y a vector of y coordinates
#' @param z a vector of z coordinates
#' @param ip Selects which pattern (see \code{\link{EOF}}, \code{\link{CCA}}) to plot
#' @param geography TRUE: plot geographical features
#' @param angle for hatching
#' @param a used in \code{\link{vec}} to scale the length of the arrows
#' @param r used in \code{\link{vec}} to make a 3D effect of plotting the arrows up in the air.
#' @param ix used to subset points for plotting errors
#' @param iy used to subset points for plotting errors
#' @param colorbar Show the color bar in the map (default TRUE). If FALSE, the
#' colorbar is not added into the map (ignored).
#' @param cex Size of symbols.
#' @param cex0 Scaling of symbols if \code{cex} is defined by a variable with
#' different size for different locations.
#' @param cex.subset ...
#' @param add.text Add abbreviated location names.
#' @param full.names Show the full name of the location.
#' @param showall Default is set to FALSE
#' @param showaxis If set to FALSE, the axis are not displayed in the plot.
#' @param fancy If set to true, will use \code{\link{col.bar}} instead of
#' \code{image} to produce the colour bar
#' @param text If TRUE, display text info on the map.The default is set to
#' FALSE
#' @param show.val Display the values of 'x' or 'FUN(x)' on top of the coloured
#' map.
#' @param legend.shrink If set, the size of the color bar is shrinked (values
#' between 0 and 1)
#' @param ... further arguments passed to or from other methods.
#' @param land if TRUE mask land, else mask ocean
#' @param what What to map: ['eof','field] for EOF pattern or the field
#' @param type - default c('fill','contour')
#' recovered from the EOFs.
#' @param fig see \code{\link{par}}
#' @param add set add=TRUE if adding the map as a subplot
#' @param nbins number of bins/colour categories
#'
#' @return A field object
#'
#' @seealso \code{\link{plot.station}}, \code{\link{showmaps}}
#' @keywords map
#' @examples
#'
#' # Select stations in ss and map the geographical location
#' # of the selected stations with a zoom on Norway.
#' ss <- select.station(cntr="NORWAY",param="precip",src="GHCND")
#' map(ss, col="blue",bg="lightblue",xlim = c(-10,30) , ylim = c(50,70), new=FALSE)
#'
#' ## Get NACD data and map the mean values
#' y <- station.nacd()
#' map(y,FUN='mean',colbar=list(pal="t2m",n=10), cex=2, new=FALSE)
#'
#' ## Adjust rotation of the color axis ticks
#' map(y,FUN='mean',colbar=list(pal="t2m",n=10,srt=0), cex=2, new=FALSE)
#'
#' # Examples of cyclone maps (map.events)
#' data(storms)
#' # Subset cyclones from the start of January 2016 lasting a minimum of 10 time steps
#' x <- subset(storms,it=c("2016-01-01","2016-01-07"),ic=list(param="trackcount",pmin=10))
#' # Map with points and lines showing the cyclone centers and trajectories
#' map(x, type=c("trajectory","points"), col="blue")
#' ## Map with only the trajectory and start and end points
#' map(x, type=c("trajectory","start","end"), col="red")
#' ## Map showing the cyclone depth (slp at center) as a color scale (rd = red scale)
#' map(x, param="pcent", type=c('trajectory','start'),
#' colbar=list(pal="rd", rev=TRUE, breaks=seq(980,1000,2)),
#' alpha=0.9, new=FALSE)
#'
#' # Example showing two maps in one figure:
#' \dontrun{
#' rr <- retrieve('~/data/data.ECAD/rr_ens_mean_0.1deg_reg.nc',it=c(2000,2001))
#' it <- 195
#' par(mfcol=c(1,2))
#' attr(rr,'variable') <- 'precip'
#' map(rr,FUN='mean',new=FALSE,type='fill',colbar=NULL,lab=paste(range(index(rr)),collapse=' - '))
#' map(subset(rr,it=it),FUN='mean',new=FALSE,type='fill',colbar=NULL,lab=as.character(index(rr)[it]))
#' }
#'
#' ## Example: plotting maps with different projections
#' t2m <- t2m.NCEP()
#'
#' # Spherical map, centered around 45 degrees E / 45 degrees N
#' map(t2m, projection="sphere", lonR=45, latR=45)
#'
#' # Spherical map showing the trend, overlayed with contours of the mean field
#' lonR <- 45; latR <- 90
#' map(t2m, FUN="trend", projection="sphere", lonR=lonR, latR=latR, type="fill")
#' spherical_contour(t2m, FUN="mean", lonR=lonR, latR=latR, add=TRUE)
#'
#' # Spherical map centered around the north pole
#' map(t2m, projection="np")
#'
#' # Projections based on the function oce::mapPlot
#' map(t2m,projection="+proj=moll")
#'
#' # Night mode: dark background
#' map(t2m, projection="np", style='night')
#'
#' @export map
map <- function(x,...) UseMethod("map")
#' @exportS3Method
#' @export
map.default <- function(x,...,FUN='mean',it=NULL,is=NULL,new=FALSE,
projection="lonlat",xlim=NULL,ylim=NULL,zlim=NULL,lab='default',
colbar= list(pal=NULL,rev=FALSE,n=10,breaks=NULL,pos=0.05,
show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,cex=2,
lonR=NULL,latR=NULL,axiR=NULL,style='plain',
verbose=FALSE,plot=TRUE,add=FALSE,useRaster=TRUE) {
## default with no arguments will produce a map showing available station
## data in the esd package.
if (verbose) print('map.default')
if (inherits(x,'station')) {
z <- map.station(x,FUN=FUN,it=it,is=is,new=new,projection=projection,
xlim=xlim,ylim=ylim,zlim=zlim,n=15,
colbar= colbar,gridlines=gridlines,verbose=verbose,
plot=plot,useRaster=useRaster,...)
invisible(z)
} else {
par0 <- par(no.readonly = TRUE) # save default, for resetting...
if (is.logical(colbar)) colbar <- NULL
## If only a few items are provided in colbar - then set the rest to the default
if (!is.null(colbar)) {
colbar <- colbar.ini(x,FUN=FUN,colbar=colbar,verbose=FALSE)
}
x <- subset(x,it=it,is=is)
X <- attr(x,'pattern')
## if zlim is specified, then mask data outside this range
if (!is.null(zlim)) {
d <- dim(X)
mask <- (X < min(zlim)) | (X > max(zlim))
X[mask] <- NA
dim(X) <- d
if (verbose) {print(zlim); print(dim(X)); print(sum(mask))}
}
if (verbose) print('map.default: Copy metadata')
attr(X,'longitude') <- lon(x)
attr(X,'latitude') <- lat(x)
attr(X,'variable') <- attr(x,'variable')
attr(X,'unit') <- attr(x,'unit')[1]
if (attr(X,'unit') =='%') attr(X,'unit') <- "'%'"
attr(X,'source') <- attr(x,'source')
attr(X,'variable') <- varid(x)
if (inherits(X,'zoo')) {
attr(X,'time') <- range(index(x))
} else if (!is.null(attr(x,'time'))) {
attr(X,'time') <- attr(x,'time')
}
if (plot) {
if (projection=="lonlat") {
z <- lonlatprojection(x=X,xlim=xlim,ylim=ylim,colbar=colbar,verbose=verbose,
lab=lab,type=type,new=new,gridlines=gridlines,useRaster=useRaster,...)
} else if (projection=="sphere") {
z <- map2sphere(x=X,lonR=lonR,latR=latR,axiR=axiR,xlim=xlim,ylim=ylim,
lab=lab,type=type,gridlines=gridlines,colbar=colbar,new=new,...)
} else if (projection=="np") {
z <- map2sphere(X,lonR=lonR,latR=90,axiR=axiR,xlim=xlim,ylim=ylim,
lab=lab,type=type,gridlines=gridlines,colbar=colbar,new=new,...)
} else if (projection=="sp") {
z <- map2sphere(X,lonR=lonR,latR=-90,axiR=axiR,new=new,xlim=xlim,ylim=ylim,
lab=lab,type=type,gridlines=gridlines,colbar=colbar,...)
} else if (length(grep('+proj=|moll|aea|utm|stere|robin',projection))>0) {
z <- map.sf(X,projection=projection,xlim=xlim,ylim=ylim,type=type,
gridlines=gridlines,colbar=colbar,...)
}
} else z <- X
invisible(z)
}
}
#' @exportS3Method
#' @export
map.matrix <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,n=15,lab="default",
colbar= list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,
ip=1,plot=TRUE) {
## If x is provided, map only x...
## default with no arguments will produce a map showing the station data in the esd package.
## image(lon(x),lat(x),x)
if (verbose) print('map.matrix')
#par0 <- par(no.readonly = TRUE) # save default, for resetting...
if (!is.null(is)) x <- subset(x,is=is) # if is is set, then call subset
if (inherits(x,'zoo')) attr(x,'time') <- range(index(x))
if (verbose) str(x)
if (plot) {
if (projection=="lonlat") {
z <- lonlatprojection(x=x,new=new,xlim=xlim,ylim=ylim,zlim=zlim,colbar=colbar,
lab=lab,type=type,gridlines=gridlines,verbose=verbose,...)
} else if (projection=="sphere") {
z <- map2sphere(x=x,new=new,xlim=xlim,ylim=ylim,zlim=zlim,colbar=colbar,
type=type,lab=lab,lonR=lonR,latR=latR,axiR=axiR,verbose=verbose,...)
} else if (projection=="np") {
z <- map2sphere(x,new=new,xlim=xlim,ylim=ylim,zlim=zlim,lonR=lonR,latR=90,
type=type,lab=lab,colbar=colbar,verbose=verbose,...)
} else if (projection=="sp") {
z <- map2sphere(x,new=new,xlim=xlim,ylim=ylim,zlim=zlim,lonR=lonR,latR=-90,
type=type,lab=lab,colbar=colbar,verbose=verbose,...)
} else if (length(grep('moll|aea|utm|stere|robin',projection))>0) {
z <- map.sf(x,projection=projection,xlim=xlim,ylim=ylim,type=type,
gridlines=gridlines,colbar=colbar,...)
} else {
z <- lonlatprojection(x=x,new=new,xlim=xlim,ylim=ylim,zlim=zlim,colbar=colbar,
lab=lab,type=type,gridlines=gridlines,verbose=verbose,...)
}
} else z <- lonlatprojection(x,xlim=xlim,ylim=ylim,zlim=zlim,colbar=colbar,plot=plot)
invisible(z)
#map.station(NULL,...)
}
#' @exportS3Method
#' @export
map.data.frame <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,n=15,
colbar= list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,
ip=1,plot=TRUE) {
if (verbose) print('map.data.frame')
#par0 <- par(no.readonly = TRUE) # save default, for resetting...
attr(x,'location') <- x$location; x$location <- NULL
attr(x,'longitude') <- x$longitude; x$longitude <- NULL
attr(x,'latitude') <- x$latitude; x$latitude <- NULL
attr(x,'country') <- x$country; x$country <- NULL
x <- as.matrix(x)
z <- map(x,it=it,is=is,new=new,projection=projection,
xlim=xlim,ylim=ylim,zlim=zlim,n=15,
colbar= colbar,type=type,gridlines=gridlines,
lonR=lonR,latR=latR,axiR=axiR,verbose=verbose,
ip=ip,plot=plot,...)
invisible(z)
}
#' @exportS3Method
#' @export
map.array <- function(x,...,FUN='mean',ip=NULL,is=NULL,new=FALSE,
projection="lonlat",na.rm=TRUE,lab="default",
xlim=NULL,ylim=NULL,zlim=NULL,##n=15,
colbar=list(col=NULL,rev=FALSE,breaks=NULL,pos=0.05,
srt=45,show=TRUE,type="r",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,plot=TRUE) {
if (verbose) print('map.array')
#par0 <- par(no.readonly = TRUE) # save default, for resetting...
if (!is.null(is)) x <- subset(x,is=is) # if is is set, then call subset
if (is.null(ip)) {
## If it is NULL, then aggregate all of 3rd dimension
D <- dim(x)
x2d <- x
dim(x2d) <- c(D[1]*D[2],D[3])
z <- apply(x2d,1,FUN,na.rm=na.rm)
z <- as.matrix(z)
dim(z) <- c(D[1],D[2])
str(z)
} else z <- x[,,ip]
d <- dim(z)
## if it is a vector of indices aggregate the selected indices
if (length(d)==3) {
dim(z) <- c(d[1]*d[2],d[3])
z <- apply(z,2,FUN)
dim(z) <- c(d[1],d[2])
}
attr(z,'longitude') <- lon(x)
attr(z,'latitude') <- lat(x)
attr(z,'variable') <- varid(x)
attr(z,'unit') <- attr(x,'unit')[1]
attr(z,'colbar') <- colbar
if (plot) map(z,new=new,xlim=xlim,ylim=ylim,zlim=zlim,colbar=colbar,
lonR=lonR,latR=latR,axiR=axiR,lab=lab,
type=type,gridlines=gridlines,projection=projection,
verbose=verbose,...)
invisible(z)
}
#' @exportS3Method
#' @export
map.comb <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,#n=15,
colbar=list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
srt=45,pos=0.05,show=TRUE,type="p",
cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,
ip=1,plot=TRUE) {
if (verbose) print('map.comb')
par0 <- par(no.readonly = TRUE) # save default, for resetting...
stopifnot(inherits(x,'eof'))
x <- subset(x,it=it,is=is)
projection <- tolower(projection)
## if (is.null(col)) col <- colscal(pal=colbar$pal,n=n-1,rev=colbar$rev) else
## if (length(col)==1) {
## pal <- col
## col <- colscal(pal=pal,n=n-1,rev=colbar$rev)
## }
if (is.null(varid(x))) attr(x,'variable') <- 'NA'
## if (tolower(varid(x))=='precip') col <- rev(col)
z <- map.eof(x=x,xlim=xlim,ylim=ylim,zlim=zlim,ip=ip,
projection=projection,colbar=colbar,new=new,
lonR=lonR,latR=latR,axiR=axiR,type=type,
gridlines=gridlines,verbose=verbose,plot=plot,...) -> result
invisible(z)
}
#' @exportS3Method
#' @export
map.eof <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",what="eof",
xlim=NULL,ylim=NULL,zlim=NULL,lab="default",
colbar=list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
srt=45,pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,
ip=1,cex=1,plot=TRUE) {
if (verbose) print('map.eof')
par0 <- par(no.readonly = TRUE) # save default, for resetting...
stopifnot(inherits(x,'eof'))
##x <- subset(x,it=it,is=is)
projection <- tolower(projection)
## REB 2016-10-19: one option is to recover the field and then maps the field
if (what=="field") {
if (verbose) print('what=field: recover the field before mapping')
x <- subset(x,it=it,is=is)
if (verbose) {print(dim(x)); range(index(x)); range(lon(x)); range(lat(x))}
y <- as.field(x)
z <- map(y,new=new,projection=projection,xlim=xlim,ylim=ylim,
zlim=zlim,colbar=colbar,type=type,gridlines=gridlines,
lonR=lonR,latR=latR,axiR=axiR,verbose=verbose,cex=cex,plot=plot)
invisible(z)
} else {
tot.var <- attr(x,'tot.var')
D <- attr(x,'eigenvalues')
var.eof <- 100* D^2/tot.var
d.eof <- dim(attr(x,'pattern'))
if (verbose) {print('Dimensions of pattern'); print(d.eof)}
if (length(d.eof)==2) dim(attr(x,'pattern')) <- c(d.eof,1)
X <- attr(x,'pattern')[,,ip]
## if zlim is specified, then mask data outside this range
if (!is.null(zlim)) {
d <- dim(X)
mask <- (X < min(zlim)) | (X > max(zlim))
X[mask] <- NA
dim(X) <- d
if (verbose) {print(zlim); print(dim(X)); print(sum(mask))}
}
##str(x)
attr(X,'longitude') <- attr(x,'longitude')
attr(X,'latitude') <- attr(x,'latitude')
attr(X,'variable') <- attr(x,'variable')
attr(X,'unit') <- attr(x,'unit')[1]
if (attr(X,'unit') =='%') attr(X,'unit') <- "'%'"
attr(X,'source') <- attr(x,'source')
attr(X,'time') <- range(index(x))
attr(X,'greenwich') <- attr(x,"greenwich")
attr(X,'colbar') <- colbar
if ( (ip==1) & !is.null(attr(x, "area.mean.expl")) )
if (attr(x, "area.mean.expl"))
type <- "fill"
if (plot) {
if (projection=="lonlat") {
z <- lonlatprojection(x=X,it=it,xlim=xlim,ylim=ylim,lab=lab,
colbar=colbar,new=new,type=type,
gridlines=gridlines,verbose=verbose,...)
} else if (projection=="sphere") {
z <- map2sphere(x=X,it=it,lonR=lonR,latR=latR,axiR=axiR,lab=lab,
xlim=xlim,ylim=ylim,type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="np") {
z <- map2sphere(X,it=it,lonR=lonR,latR=90,axiR=axiR,lab=lab,
xlim=xlim,ylim=ylim,type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="sp") {
z <- map2sphere(X,it=it,lonR=lonR,latR=-90,axiR=axiR,lab=lab,
xlim=xlim,ylim=ylim,type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (length(grep('moll|aea|utm|stere|robin',projection))>0) {
z <- map.sf(X,projection=projection,xlim=xlim,ylim=ylim,type=type,
gridlines=gridlines,colbar=colbar,...)
}
} else z <- X
}
invisible(z)
}
#' @exportS3Method
#' @export
map.ds <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,
colbar=list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
srt=45,pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,plot=TRUE) {
if (verbose) print('map.ds')
par0 <- par(no.readonly = TRUE) # save default, for resetting...
stopifnot(inherits(x,'ds'))
x <- subset(x,is=is)
## REB 2015-03-26
if (inherits(x,'mvcomb')) {
z <- map.mvcomb(x,it=it,verbose=verbose,new=new,
xlim=xlim,ylim=ylim,projection=projection,
lonR=lonR,latR=latR,axiR=axiR,gridlines=gridlines,
colbar=colbar,...) ##col=col,breaks=breaks)
invisible(z)
} else if (inherits(x,'pca')) {
z <- map.pca(x,it=it,verbose=verbose,new=new,
xlim=xlim,ylim=ylim,projection=projection,
lonR=lonR,latR=latR,axiR=axiR,gridlines=gridlines,
colbar=colbar,...) ##col=col,breaks=breaks)
invisible(z)
} else if (inherits(x,'eof')) {
z <- map.eof(x,it=it,verbose=verbose,new=new,
xlim=xlim,ylim=ylim,projection=projection,
lonR=lonR,latR=latR,axiR=axiR,gridlines=gridlines,
colbar=colbar,...) ##col=col,breaks=breaks)
invisible(z)
}
projection <- tolower(projection)
if (!is.null(attr(x,'pattern'))) {
X <- attr(x,'pattern')
if (is.list(X)) {
X <- X[[1]]
}
# Check if there are several patterns: one for each month/seasons
d <- dim(X)
if (length(d)>2) {
dim(X) <- c(d[1],d[2]*d[3])
X <- colMeans(X)
dim(X) <- c(d[2],d[3])
attr(X,'longitude') <- lon(attr(x,'pattern'))
attr(X,'latitude') <- lat(attr(x,'pattern'))
}
attr(X,'variable') <- varid(attr(x,'eof'))
attr(X,'unit') <- 'weight'
} else X <- NULL
unit <- attr(x,'unit')
if ( (is.na(unit) | is.null(unit)) ) unit <- " "
for (i in 1:length(unit)) {
if ((unit[i]=='degree Celsius') | (unit[i]=='deg C') | (unit[i]=='degC'))
unit[i] <- 'degree*C'
}
if (is.null(X)) {
attr(X,'unit') <- unit
attr(X,'source') <- attr(x,'source')
}
if ((plot) & (!is.null(X))) {
if (projection=="lonlat") {
z <- lonlatprojection(x=X,colbar=colbar,verbose=verbose,xlim=xlim,ylim=ylim,
type='fill',gridlines=gridlines,new=new,...)
if (is.list(attr(x,'pattern'))) {
Xa <- attr(x,'pattern')
nms <- names(Xa)
col <- c('black','darkgreen','grey','yellow','magenta','cyan',
'brown','white','green')
for (i in (2:length(nms)))
contour(lon(Xa[[i]]),lat(Xa[[i]]),Xa[[i]],add=TRUE,col=col[i])
} else if (sum(is.element(type,'contour'))>0)
contour(lon(X),lat(X),X,add=TRUE,col="grey50")
} else if (projection=="sphere") {
z <- map2sphere(x=X,lonR=lonR,latR=latR,axiR=axiR,
xlim=xlim,ylim=ylim,type=type,
gridlines=gridlines,colbar=colbar,
new=new,verbose=verbose,...)
} else if (projection=="np") {
z <- map2sphere(X,lonR=lonR,latR=90,axiR=axiR,
xlim=xlim,ylim=ylim,type=type,
gridlines=gridlines,colbar=colbar,
new=new,verbose=verbose,...)
} else if (projection=="sp") {
z <- map2sphere(X,lonR=lonR,latR=-90,axiR=axiR,
xlim=xlim,ylim=ylim,type=type,
gridlines=gridlines,colbar=colbar,
new=new,verbose=verbose,...)
}
} else z <- X
invisible(z)
}
#' @exportS3Method
#' @export
map.field <- function(x,...,FUN='mean',it=NULL,is=NULL,new=FALSE,
projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,n=15,
colbar= list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,
na.rm=TRUE,plot=TRUE,add=TRUE) {
stopifnot(inherits(x,'field'))
if (verbose) print('map.field')
par0 <- par(no.readonly = TRUE)
x <- subset(x,it=it,is=is)
#print(length(x)); print(attr(x,'dimensions')[1:2])
projection <- tolower(projection)
if (FUN=='trend') FUN <- 'trend.coef'
if (!is.null(xlim)) {
if (xlim[1] < 0) x <- g2dl(x,greenwich=FALSE)
}
#str(X)
X <- coredata(x)
## Fudge, since these don't work with apply
if (FUN=='firstyear') attr(x,FUN) <- firstyear(x)
if (FUN=='lastyear') attr(x,FUN) <- lastyear(x)
natts <- names(attributes(x))
## REB 2019-01-30
useattr <- FALSE
if(sum(is.element(natts,FUN))) useattr <- TRUE
if(useattr) {
if (verbose) print(paste('Use attribute',FUN))
X <- attr(x,FUN)
} else
## If one time slice, then map this time slice
if (dim(X)[1]==1) {
if (verbose) print('One point in time')
X <- coredata(x[1,])
} else if (is.null(X)) {
if (verbose) print('Data is a vector')
X <- coredata(X)
} else if (inherits(X,"matrix")) {
if (verbose) {print(paste('Data is a matrix. FUN=',FUN)); print(dim(x))}
## If several time slices, map the required statistics
good <- apply(coredata(x),2,nv) > 1
X <- rep(NA,length(good))
xx <- x[,good]
X[good] <- apply(coredata(xx),2,FUN=FUN,na.rm=na.rm)
} else {print('Do not know what to do')}
## if zlim is specified, then mask data outside this range
if (!is.null(zlim)) {
d <- dim(X)
mask <- (X < min(zlim)) | (X > max(zlim))
rng <- range(X,na.rm=TRUE)
X[mask] <- NA
dim(X) <- d
if (verbose) print(paste('zlim=',zlim[1],zlim[2],
' sum(mask)=',sum(mask),
' range(X)=',rng[1],rng[2]))
}
#print(length(X))
attr(X,'longitude') <- attr(x,'longitude')
attr(X,'latitude') <- attr(x,'latitude')
attr(X,'variable') <- attr(x,'variable')[1]
# if (attr(x,'unit')=="deg C") attr(X,'unit') <- expression(degree*C) else
unit <- attr(x,'unit')[1]
if (unit =='%') unit <- "'%'"
if ( (is.na(unit) | is.null(unit)) ) unit <- " "
if ((unit=='degree Celsius') | (unit=='deg C') | (unit=='degC'))
unit <- 'degree*C'
unit <- as.character(unit)
attr(X,'unit') <- unit
attr(X,'source') <- attr(x,'source')
attr(X,'time') <- range(index(x))
attr(X,'method') <- FUN
attr(X,'timescale') <- class(x)[2]
if (verbose) {print(length(X)); print(attr(x,'dimensions'))}
dim(X) <- attr(x,'dimensions')[1:2]
if (verbose) {print(str(X)); print(summary(c(X)))}
if (plot) {
if (projection=="lonlat") {
z <- lonlatprojection(x=X,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
colbar=colbar,type=type,new=new,
gridlines=gridlines,verbose=verbose,...)
} else if (projection=="sphere") {
z <- map2sphere(x=X,xlim=xlim,ylim=ylim,zlim=zlim,#n=n,
lonR=lonR,latR=latR,axiR=axiR,
type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="np") {
z <- map2sphere(X,xlim=xlim,ylim=ylim,zlim=zlim,#n=n,
lonR=lonR,latR=90,axiR=axiR,
type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="sp") {
z <- map2sphere(X,xlim=xlim,ylim=ylim,zlim=zlim,#n=n,
lonR=lonR,latR=-90,axiR=axiR,
type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (length(grep('moll|aea|utm|stere|robin',projection))>0) {
z <- map.sf(X,projection=projection,xlim=xlim,ylim=ylim,type=type,
gridlines=gridlines,colbar=colbar,...)
}
} else z <- X
invisible(z)
}
#' @exportS3Method
#' @export
map.corfield <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,n=15,
colbar= list(pal=NULL,rev=FALSE,n=NULL,
breaks=seq(-1,1,by=0.05),pos=0.05,show=TRUE,
type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,plot=TRUE) {
if (verbose) print("map.corfield")
stopifnot(inherits(x,'corfield'))
par0 <- par(no.readonly = TRUE) # save default, for resetting...
x <- subset(x,it=it,is=is,verbose=verbose)
projection <- tolower(projection)
dim(x) <- attr(x,'dimensions')[1:2]
## if (!is.null(colbar)) colbar$pal <- varid(x)[2] ## AM 08-07-2015 comment
attr(x,'variable') <- paste(varid(x),collapse='/')
#if (length(attr(x,'unit'))>1) attr(x,'unit') <- paste(attr(x,'unit'),collapse='/')
attr(x,'unit') <- attr(x,'unit')[1]
## if zlim is specified, then mask data outside this range
if (!is.null(zlim)) {
if (verbose) print(zlim)
d <- dim(x)
mask <- (x < min(zlim,na.rm=TRUE)) | (x > max(zlim,na.rm=TRUE))
x[mask] <- NA
dim(x) <- d
if (verbose) {print(zlim); print(dim(x)); print(sum(mask))}
}
if (verbose) {print(projection); print(dim(x))}
if (plot) {
if (projection=="lonlat") {
z <- lonlatprojection(x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
colbar=colbar,type=type,new=new,verbose=verbose,
gridlines=gridlines,...)
} else if (projection=="sphere") {
z <- map2sphere(x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
lonR=lonR,latR=latR,axiR=axiR,type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="np") {
z <- map2sphere(x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
lonR=lonR,latR=90,axiR=axiR,type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="sp") {
z <- map2sphere(x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
lonR=lonR,latR=-90,axiR=axiR,type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
}
} else z <- x
if (!is.null(attr(x,'x.longitude')) & !is.null(attr(x,'x.latitude')))
points(attr(x,'x.longitude'),attr(x,'x.latitude'),lwd=2,cex=1.2)
invisible(z)
}
#' @exportS3Method
#' @export
map.trend <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,n=15,
colbar= list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,plot=TRUE) {
if (verbose) print('map.trend')
stopifnot(inherits(x,'field'),inherits(x,'trend'))
par0 <- par(no.readonly = TRUE) # save default, for resetting...
x <- subset(x,it=it,is=is)
projection <- tolower(projection)
X <- attr(x,'pattern')
## if zlim is specified, then mask data outside this range
if (!is.null(zlim)) {
d <- dim(x)
mask <- (x < min(zlim)) | (x > max(zlim))
x[mask] <- NA
dim(x) <- d
if (verbose) {print(zlim); print(dim(x)); print(sum(mask))}
}
attr(X,'longitude') <- attr(x,'longitude')
attr(X,'latitude') <- attr(x,'latitude')
attr(X,'variable') <- paste(attr(x,'variable'),'trend')
attr(X,'time') <- range(index(x))
attr(X,'unit') <- paste('d',attr(x,'unit'),'/decade')
attr(X,'source') <- attr(x,'source')
dim(X) <- attr(x,'dimension')[1:2]
#str(X)
if (plot) {
if (projection=="lonlat") {
z <- lonlatprojection(x=x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
colbar=colbar,type=type,new=new,
verbose=verbose,gridlines=gridlines,...)
} else if (projection=="sphere") {
z <- map2sphere(x=x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
lonR=lonR,latR=latR,axiR=axiR,
type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="np") {
z <- map2sphere(x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
lonR=lonR,latR=90,axiR=axiR,
type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
} else if (projection=="sp") {
z <- map2sphere(x,xlim=xlim,ylim=ylim,zlim=zlim,n=n,
lonR=lonR,latR=-90,axiR=axiR,
type=type,gridlines=gridlines,
colbar=colbar,new=new,verbose=verbose,...)
}
} else z <- X
invisible(z)
}
#' @exportS3Method
#' @export map.pca
map.pca <- function(x,...,it=NULL,is=NULL,ip=1,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,FUN='mean',##n=15,
colbar=list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
srt=45,pos=0.05,show=TRUE,type="p",cex=1,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
#cex.axis=1,cex.main=1,cex.lab=1,
#add=FALSE,fig=c(0,1,0.05,0.95),
lonR=NULL,latR=NULL,axiR=NULL,verbose=FALSE,plot=TRUE) {
##
if (verbose) print(paste('map.pca',FUN))
par0 <- par(no.readonly = TRUE) # save default, for resetting...
if(inherits(x,"trajectory")) {
z <- map.pca.trajectory(x,projection=projection,lonR=lonR,latR=latR,
xlim=xlim,ylim=ylim,...)
} else {
args <- list(...)
#print(args)
## REB 2016-11-02 fix
if (is.null(dim(attr(x,'pattern')))) {
dim(attr(x,'pattern')) <- c(1,length(attr(x,'pattern')))
}
X <- rbind(attr(x,'pattern')[,ip],attr(x,'pattern')[,ip])
#print(dim(X))
#str(x)
X <- attrcp(x,X)
## if zlim is specified, then mask data outside this range
if (!is.null(zlim)) {
d <- dim(X)
mask <- (X < min(zlim)) | (X > max(zlim))
X[mask] <- NA
dim(X) <- d
if (verbose) {print(zlim); print(dim(X)); print(sum(mask))}
}
if (verbose) print('map.pca: copy metadata')
attr(X,'longitude') <- lon(x)
attr(X,'latitude') <- lat(x)
attr(X,'mean') <- NULL
class(X) <- 'station'
##if (is.null(colbar$col) | is.null(colbar)) {
## colbar$col <- colscal(30,pal=varid(x))
##}
if (verbose) str(X)
if (is.element(FUN,args)) {
z <- map.station(X,new=new,colbar=colbar,
xlim=xlim,ylim=ylim,zlim=zlim,
plot=plot,#add=add,fig=fig,
verbose=verbose,...)
} else {
z <- map.station(X,new=new,colbar=colbar,FUN=FUN,
xlim=xlim,ylim=ylim,zlim=zlim,
plot=plot,#add=add,fig=fig,
verbose=verbose,...)
}
}
invisible(z)
}
#' @exportS3Method
#' @export
map.mvr <- function(x,...,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,
colbar= list(pal=NULL,rev=FALSE,n=10,breaks=NULL,
pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
type=c("fill","contour"),gridlines=FALSE,
verbose=FALSE,plot=TRUE) {
if(verbose) print("map.mvr")
par0 <- par(no.readonly = TRUE) # save default, for resetting...
x <- subset(x,it=it,is=is)
z <- map.field(x,new=new,FUN="mean",colbar=colbar,xlim=xlim,ylim=ylim,
verbose=verbose,plot=TRUE,...) -> z
invisible(z)
}
#' @exportS3Method
#' @export
map.cca <- function(x,...,ip=1,it=NULL,is=NULL,new=FALSE,projection="lonlat",
xlim=NULL,ylim=NULL,zlim=NULL,
colbar1=list(pal=NULL,rev=FALSE,n=10,
breaks=seq(-1,1,by=0.1),type="p",
cex=2,show=FALSE,h=0.6,v=1,pos=0.05),
colbar2= NULL,
fig1=NULL,fig2=NULL,add=FALSE,
type=c("fill","contour"),gridlines=FALSE,
lonR=NULL,latR=NULL,axiR=NULL,cex=2,
plot=TRUE,verbose=FALSE) {
if (verbose) print('map.cca')
## KMP 2023-02-07: It's not a good idea to set the layout here
## because map.cca is used in plot.cca and this will interfere with
## the layout specified there
#layout(matrix(c(1,2),1,2,byrow = TRUE), rep(1,2), rep(1,2), TRUE)
if (is.null(colbar2)) colbar2 <- colbar1
##x <- subset(x,it=it,is=is)
## For plotting, keep the same kind of object, but replace the patterns in
## the eof/pca with the CCA patterns
Y <- x$Y
##print(dim(attr(Y,'pattern'))); print(dim(U))
##attr(Y,'pattern') <- U
U <- x$B.m
dim(U) <- c(dim(attr(Y,'pattern'))[-length(dim(attr(Y,'pattern')))],
length(x$ip))
attr(Y,'pattern') <- U
attr(Y,'eigenvalues') <- rep(1,length(x$ip))
attr(Y,'time') <- range(index(x))
X <- x$X
##print(dim(attr(X,'pattern'))); print(dim(V))
##attr(X,'pattern') <- V
V <- x$A.m
dim(V) <- c(dim(attr(X,'pattern'))[-length(dim(attr(X,'pattern')))],
length(x$ip))
attr(X,'pattern') <- V
attr(X,'eigenvalues') <- rep(1,length(x$ip))
attr(X,'time') <- range(index(x))
z1 <- map(Y,ip=ip,xlim=xlim,ylim=ylim,type=type,cex=cex,
projection=projection,lonR=lonR,latR=latR,axiR=axiR,
gridlines=gridlines,FUN='mean',verbose=verbose,
colbar=colbar1,showall=FALSE,new=FALSE,plot=plot)
z2 <- map(X,ip=ip,xlim=xlim,ylim=ylim,type=type,cex=cex,
projection=projection,lonR=lonR,latR=latR,axiR=axiR,
gridlines=gridlines,FUN='mean',verbose=verbose,
colbar=colbar2,showall=FALSE,new=FALSE,plot=plot)
invisible(list(z1 = z1, z2 = z2))
}
#' @exportS3Method
#' @export
map.events <- function(x,Y=NULL,...,it=NULL,is=NULL,xlim=NULL,ylim=NULL,main=NULL,
param=NA,alpha=0.3,lwd=3,col="black",bg="white",pch=21,cex=1,
colbar=list(pal="budrd",rev=FALSE,n=10,breaks=NULL,
srt=45,pos=0.05,show=TRUE,type="p",cex=2,h=0.6,v=1),
showaxis=TRUE, fig=NULL, #fig=c(0,1,0.05,0.95),
mgp=c(2,0.5,0), mar=rep(2,4),
lty=1,type=c("points","trajectory","start","end"),
border=FALSE,
projection="lonlat",latR=NULL,lonR=NULL,new=TRUE,
verbose=FALSE) {
if(verbose) print("map.events")
x0 <- x
x <- subset(x,it=it,is=is,verbose=verbose)
if(is.null(attr(x,"calendar"))) calendar <- "gregorian" else calendar <- attr(x,"calendar")
if(is.null(it) & dim(x)[1]>0) {
if (requireNamespace("PCICt", quietly = TRUE)) {
it <- range(PCICt::as.PCICt(as.character(x$date),cal=calendar,format="%Y%m%d"))
} else {
it <- range(as.Date(as.character(x$date),cal=calendar,format="%Y%m%d"))
}
}
if (is.null(is$lon) & !is.null(xlim)) {
is$lon <- xlim
} else if (is.null(is$lon) & is.null(xlim)) {
if(length(Y)>0) {
is$lon <- range(lon(Y))
} else if(dim(x)[1]>0) {
is$lon <- range(x[,"lon"])+c(-5,5)
}
}
if (is.null(xlim) & projection=="lonlat") xlim <- is$lon
if(projection=="lonlat" & !any(xlim<0) & any(xlim>180)) x <- g2dl(x,greenwich=TRUE)
if (is.null(is$lat) & !is.null(ylim)) {
is$lat <- ylim
} else if (is.null(is$lat) & is.null(ylim)) {
if(length(Y)>0) {
is$lat <- range(lat(Y))
} else if(dim(x)[1]>0) {
is$lat <- range(x[,"lat"])+c(-2,2)
}
}
if (is.null(ylim) & projection=="lonlat") ylim <- is$lat
if (!is.null(Y)) {
Y <- subset(Y,is=is,verbose=verbose)
if(length(Y)>0) {
if(dim(x)[1]==0) {
Y <- subset(Y,it=it,verbose=verbose)
} else {
ty <- index(Y)
if (inherits(Y,"month")) {
tx <- round(x[,"date"]*1E-2)*1E2+1
ty <- as.numeric(format(ty,"%Y%m%d"))
} else if (inherits(ty,"Date")) {
tx <- x[,"date"]
ty <- as.numeric(format(ty,"%Y%m%d"))
} else if (inherits(ty,c("POSIXt","PCICt"))) {
tx <- x[,"date"]*1E2 + x[,"time"]
ty <- as.numeric(format(ty,"%Y%m%d%H"))
}
ii <- is.element(ty,tx)
Y <- subset(Y,it=ii)
}
}
}
if(projection=="np") latR <- 90 else
if(projection=="sp") latR <- -90
if(length(Y)!=0) {
if (is.null(lonR)) lonR <- mean(lon(Y))
if (is.null(latR)) latR <- max(lat(Y))
z <- map(Y, colbar=colbar, new=new, projection=projection, main="",
fig=fig, mar=mar, mgp=mgp, showaxis=showaxis,
add=add, xlim=xlim, ylim=ylim,
latR=latR, lonR=lonR, verbose=verbose)
} else {
if(!is.null(xlim)) {
lonR <- mean(xlim)
} else if (is.null(lonR)) {
if (dim(x)[1]>0) {
lonR <- mean(x[,"lon"])
} else {
lonR <- 0
}
}
if(!is.null(ylim) & is.null(latR)) {
latR <- mean(ylim)
#latR <- sign(ylim[ylim==max(abs(ylim))])*max(abs(ylim))
} else if (is.null(latR)) {
if(dim(x)[1]>0) {
latR <- mean(x[,"lat"])
#latR <- sign(x[,"lat"][x[,"lat"]==max(abs(x[,"lat"]))])*max(abs(x[,"lat"]))
} else {
latR <- 90
}
}
xs <- events2station(x, FUN="location", param="pcent", verbose=verbose)
map(xs, FUN="mean", col="grey", cex=0.1, pch='.',
new=new, projection=projection, main="", xlab="", ylab="",
fig=fig, mar=mar, mgp=mgp, showaxis=showaxis,
border=border,
xlim=xlim, ylim=ylim, latR=latR, lonR=lonR,
verbose=verbose)
}
if(dim(x)[1]>0) {
cols <- adjustcolor(col,alpha.f=alpha)
if("points" %in% type) {
if(verbose) print("plot points")
if(projection=="lonlat") {
points(x[,"lon"],x[,"lat"],col=cols,bg=bg,cex=cex,pch=pch,lwd=lwd)
} else {
theta <- pi*x[,"lon"]/180
phi <- pi*x[,"lat"]/180
ax <- sin(theta)*cos(phi)
ay <- cos(theta)*cos(phi)
az <- sin(phi)
if (verbose) {print('Rotation:');print(dim(rotM(x=0,y=0,z=lonR))); print(dim(rbind(ax,ay,az)))}
a <- rotM(x=0,y=0,z=lonR) %*% rbind(ax,ay,az)
a <- rotM(x=latR,y=0,z=0) %*% a
ax <- a[1,]; ay <- a[2,]; az <- a[3,]
points(ax[ay>0],az[ay>0],col=cols,bg=bg,cex=cex,pch=pch,lwd=lwd)
}
}
if("trajectory" %in% colnames(x0) &
any(c("trajectory","start","end") %in% type)) {
xt <- subset(x0,it=(x0$trajectory %in% x$trajectory))
if(!("trackcount" %in% names(x)) & dim(xt)[1]>1) {
xt <- trackstats(xt)
xt <- subset(xt,it=xt$trackcount>1)
}
if(dim(xt)[1]>1) {
xall <- as.trajectory(xt,nmin=2,n=45,verbose=verbose)
map.trajectory(xall,lty=lty,lwd=lwd,alpha=alpha,new=FALSE,
col=col,lonR=lonR,latR=latR,
projection=projection,type=type,param=param,
showaxis=FALSE,add=TRUE,
colbar=colbar,verbose=verbose,...)
}
}
}
period <- unique(c(min(it),max(it)))
if (!is.null(period) & length(Y)==0) {
title(sub = paste(period,collapse=" - "))
# text(par("usr")[1] + 0.05*diff(range(par("usr")[3:4])),
# par("usr")[4] - 0.05*diff(range(par("usr")[3:4])),
# paste(period,collapse=" - "),pos=4,cex=0.75,col="grey30")
}
if (!is.null(main)) {
text(par("usr")[1] + 0.05*diff(range(par("usr")[3:4])),
par("usr")[4] - 0.10*diff(range(par("usr")[3:4])),
main,pos=4,cex=1,col="black")
}
#par(par0) # reset to default
}
#' Function that masks either ocean or land
#'
#' Uses topography from \code{\link{etopo5}} to mask either land or ocean.
#'
#' @param x a \code{field} object
#' @param land a boolean; if TRUE mask land, if FALSE mask ocean
#'
#' @export
mask <- function(x,land=FALSE) {
data(etopo5, envir = environment())
h <- regrid(etopo5,is=x)
if (!land) {
h[h < -5] <- NA
} else {
h[h > 5] <- NA
}
X <- coredata(x)
if (inherits(x,'zoo')) X[,is.na(h)] <- NA else
if (length(x)==length(h)) X[is.na(h)] <- NA
if (inherits(x,'zoo')) X -> coredata(x) else x <- X
return(x)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.