oceanmap Tutorial | Part 2 - Visualizing and Analyzing Spatial Oceanographic Data

oceanmap ggplot netcdf raster bathymetry

In this second oceanmap tutorial we will learn how to map and analyze spatial oceanographic (remote sensing) data.

Robert K. Bauer http://www2.hawaii.edu/~rkbauer (Hawai’i Institute of Marine Biology
University of Hawai’i at Mānoa)https://scholar.google.com/citations?hl=en&user=J-0_tdbR2tgC
09-17-2020

Getting started | Requirements

To run this tutorial we will need oceanmap version >= 0.13. You can find the newest version on github

## install or load package
# install.packages("oceanmap") # from CRAN
# library(xfun)
# install_github("rkbauer/oceanmap") # newest version from github
library("oceanmap")

## Package overview and version:
?oceanmap 
help(package="oceanmap") ## list of functions

Introduction

Visualizing data is a crucial step in analyzing and exploring data. During the last two decades the statistical programming language R has become a major tool for data analyses and visualization across different fields of science. However, creating figures ready for scientific publication can be a tricky and time consuming task. The oceanmap package provides some helpful functions to facilitate and optimize the visualization of geographic and oceanographic data, such as satellite and bathymetric data sets. Its major functions are

These functions were written in a way that they do not require a large amount of their numerous arguments to be specified but still return nice plots. Each of these functions will be subsequently discussed. A closely related problem represents the extraction of spatial data at defined positions/areas. Some examples on this will be discussed in an extra section.

Adding a colorbar to plotmap | The set.colorbar-function

Setting up the colorbar for an image plot in R is particularly tricky. Common plot functions, such as image.plot of the fields-package set the colorbar to a defined margin, but lack manipulation procedures. Setting up a colorbar by hand requires a lot of data input and is hence time consuming. In particular four different arguments are needed:

The set.colorbar-function of the oceanmap-package comes with 3 ways to define the colorbar position:

  1. defining its spatial extent (arguments cbx, cby)

  2. defining argument cbpos with a single letter (“b”, “I”, “t”, "r) that indicates the position of the colorbar (bottom, left, top, right)

  3. set the position of colorbar manually with the mouse cursor (run set.colorbar() without defining cbx, cby or cbpos).

n either case, the spatial extent of the thus defined colorbar position and extent will be returned (as cbx and cby) that can be reused in later function calls. This feature is further included in the add.region- and v-functions to set up the (default) colorbar placement of regions.

Note that the colormap and ticks of the colorbar can be defined through additional arguments of set.colorbar()

Example 1: plot colorbars manually

par(mar=c(5,8,3,8))
plot(0.5,0.5,xlim=c(0,1),ylim=c(0,1))
set.colorbar(cbx=c(0, 1), cby=c(-.3, -.4)) # bottom
set.colorbar(cby=c(0, 1), cbx=c(-.4, -.3)) # left
set.colorbar(cbx=c(0, 1), cby=c(1.2, 1.3)) # top
set.colorbar(cby=c(0, 1), cbx=c(1.2, 1.3)) # right

Example 2: use cbpos

par(mar=c(5,8,3,8))
plot(0.5,0.5,xlim=c(0,1),ylim=c(0,1))
set.colorbar(cbpos='b') # bottom
set.colorbar(cbpos='l') # left
set.colorbar(cbpos='t') # top
set.colorbar(cbpos='r') # right

Example 3: interactive placement

par(mar=c(5,8,3,8))
plot(0.5,0.5,xlim=c(0,1),ylim=c(0,1))
cb <- set.colorbar() # interactive
plot (0.5,0.5,xlim=c(0,1),ylim=c(0,1))
set.colorbar(cbx=cb$cbx, cby=cb$cby) # reuse stored colorbar

Available colormaps

oceanmap comes with a set of pre-installed colormaps. The jet.light colormap is semitransparent and useful when visualizing overlapping data sets. The year.jet colormap starts and ends with similar colors and is therefore particularly useful when analyzing seasonal patterns in data sets. The haxby colormap is the standard colormap for bathymetry data, starting with a white color.

Example 4: available colormaps

data('cmap') # load color maps data
names(cmap) # list available color maps
 [1] "ano"            "bathy"          "blue"          
 [4] "chla"           "green"          "haxby"         
 [7] "jet"            "rainbow"        "red"           
[10] "sst"            "haxbyrev"       "orange"        
[13] "year.jet"       "dark.blue"      "jetrev"        
[16] "light.jet"      "white2black"    "black2white"   
[19] "white2darkgrey"

Instead of using preinstalled colormaps, you can also define your own one:

Example 4: own colormaps

setwd(system.file("test_files", package="oceanmap"))
gz.files <- Sys.glob('*.gz')
# figure(width=15,height=15)
par(mfrow=c(4,5))
# for(n in names(cmap)) v(gz.files[2], v_area='lion', pal=n, adaptive.vals=TRUE, main=n)
## define new color maps from blue to red to white:
n <- colorRampPalette(c('blue','red','white'))(100)
# v(gz.files[2], v_area='lion', pal=n, adaptive.vals=TRUE, main="own colormap")

The v-function: Creating image-plots of spatial data

The v-function combines the advantages of the plotmap and set.colorbar to visualize 2D (oceanographic) data. To facilitate plotting, it is further capable of handling different input formats. Valid formats are:

Note that for plotting the input data will be internally transformed into a Raster-object, no matter which of the valid input format was selected. Examples to visualize matrix and array objects will not be discussed here but are given in ?matrix2raster(). The other input data formats are discussed in the following sections.

v() and RasterLayers:

The standard object type to handle spatial data in R are Raster-objects. Here some examples to visualize such objects with v().

Example 1: load & plot a sample Raster-object

setwd(system.file("test_files", package="oceanmap"))
load("medw4_modis_sst2_4km_1d_20020705_20020705.r2010.0.qual0.Rdata")
dat <- raster::crop(dat,extent(c(0,10,40,44))) ## crop data, xlim/ylim not yet implemented in v()
print(dat)
class      : RasterLayer 
dimensions : 96, 240, 23040  (nrow, ncol, ncell)
resolution : 0.04166667, 0.04166667  (x, y)
extent     : 0, 10, 40, 44  (xmin, xmax, ymin, ymax)
crs        : +proj=longlat +ellps=WGS84 
source     : memory
names      : layer 
values     : 16.8, 25.8  (min, max)
v(dat, main="Raster-object", cbpos='r')

v() and nefcdf-files

Example 2: load & plot sample netcdf-file (‘.nc’-file)

option a) load netcdf-file with ncdf4-package and plot it

setwd(system.file("test_files", package="oceanmap"))
ncfiles <- Sys.glob('*.nc') # load list of sample-'.nc'-files
par(cex=.7)
print(ncfiles)
[1] "herring_lavae.nc" "topo.v02.nc"     
library('ncdf4')
ncdf <- nc_open(ncfiles[1])
print(ncdf)
File herring_lavae.nc (NC_FORMAT_CLASSIC):

     1 variables (excluding dimension variables):
        float Conc[lon,lat,time]   
            _FillValue: -1

     3 dimensions:
        lon  Size:352
        lat  Size:310
        time  Size:4   *** is unlimited ***
            units: seconds since 2006-03-01 00:00:00
par(cex=.7)
v(obj = ncdf, cbpos="r")

option b) load and plot netcdf-file as RasterStack object

setwd(system.file("test_files", package="oceanmap"))
nc <- nc2raster(ncfiles[1])
File herring_lavae.nc (NC_FORMAT_CLASSIC):

     1 variables (excluding dimension variables):
        float Conc[lon,lat,time]   
            _FillValue: -1

     3 dimensions:
        lon  Size:352
        lat  Size:310
        time  Size:4   *** is unlimited ***
            units: seconds since 2006-03-01 00:00:00

converting array to RasterStack object

ATTENTION: nc2raster()-calls require a “varname” selection if the netcdf-file holds multiple spatial variables.

setwd(system.file("test_files", package="oceanmap"))
## attention you may have to increase margin spacings 
## for correct colorbar text rendering
par(cex=.7)
v(nc, cbpos="r") # plot RasterStack object

option c) plot netcdf-file directly

setwd(system.file("test_files", package="oceanmap"))
ncfiles <- Sys.glob('*.nc') # load list of sample-'.nc'-files
par(mfrow=c(2,1),mar=c(2,5,2,5)*1.2,cex=.6)
v(ncfiles[1], cbpos="r")
v(ncfiles[1], cbpos="r", replace.na=TRUE)

plot multiple layers:

setwd(system.file("test_files", package="oceanmap"))
par(mfrow=c(2,2),mar=c(5,5,5,5))
v(ncfiles[1], t=1:4, cbpos="r")

ggplotmap and raster files

The newest version of oceanmap includes now a gglplot and plotly-version of the base-function plotmap(). You can use gglplotmap() to create land masks, which you can add to existing ggplots. This is particularly helpful when you are dealing with rasterized data:

library(dplyr)
library(ggplot2)
data(cmap)
setwd(system.file("test_files", package="oceanmap"))
nc <- nc2raster(ncfiles[1])
File herring_lavae.nc (NC_FORMAT_CLASSIC):

     1 variables (excluding dimension variables):
        float Conc[lon,lat,time]   
            _FillValue: -1

     3 dimensions:
        lon  Size:352
        lat  Size:310
        time  Size:4   *** is unlimited ***
            units: seconds since 2006-03-01 00:00:00

converting array to RasterStack object
rs2df <- nc[[1]] %>% ## take first layer
         rasterToPoints() %>% ## convert raster to xyz matrix
         as.data.frame() ## convert to data frame
names(rs2df) <- c("Lon","Lat","Conc") ## reset names (important for ggplotmaply hover text)
ggobj <- ggplot() + geom_raster(data = rs2df, aes(x=Lon,y=Lat,fill=Conc)) 
ggobj_with_land_mask <- ggplotmap(add_to = ggobj) + 
                        scale_fill_gradientn(colours=cmap$jet) # change colorbar
ggobj_with_land_mask 

ggplotmaply | The ggplotly version for ggplotmap

Now let’s convert this figure into an interative visualization using the ggplotmaply-function: (Note that the scale bars of ggplotmap() can not be inlcuded in the plotly visualizations.)

ggplotmaply(ggobj_with_land_mask)