---
author: "An-Chi Ho"
date: "`r Sys.Date()`"
output: html_document
vignette: >
  %\VignetteEngine{R.rsp::md}
  %\VignetteIndexEntry{Visualisation}
  %\usepackage[utf8]{inputenc}
---

We will use the data loaded in [data_loading.md](#data-loading) in this vignette. 
Please follow that vignette first to get the data if you want to replicate the results in this vignette.

# Map plotting

In this vignette, we will go through the functions that plot the map type of figures: 
`VizEquiMap()`, `VizRobinson()`, `VizStereoMap()`, `VizAnimateMap()`, `VizLayout()`, `VizSection()`.

This group of functions allows to plot grid data (i.e. defined over latitudes 
and longitudes) on a rectangular equidistant or stereographic projection,
as well as depth section (i.e. the cross section of latitudes/longitudes and heights).

`VizEquiMap()` and `VizStereoMap()` share some traits:
 - Both expect a data matrix in the parameter `var` of dimensions 
`c(n. of latitudes, n. of longitudes)`, `lat` with a vector with the latitudes 
of the centers of the grid cells and `lon`, a vector with the longitudes. 
 - The N colors to paint the grid cells with (via `cols`) as well as the N +
1 threshold magnitudes (via `brks`) that will allow to assign each grid cell 
value one of the N colours. The colour for any missing values can be adjusted 
with `colNA`.
 - Whether to fill the map continents or only draw coast wires can be adjusted
with `filled.continents`.
 - A matrix of `dots` can be plotted over the drawn map to, e.g., highlight 
cells where a skill has been greatest or most significant.
 - A legend can be drawn (unless disabled with `drawleg`) and the amount of 
ticks on that legend can be adjusted with `subsampleg`.
 - They accept any additional parameters via the parameter `...` to be sent to
the underlying R graphics `image()` function for a fine tuning.

### VizEquiMap()

VizEquiMap() plots the map with rectangular equidistant projection. 
It has various parameters to adjust the visualization.

#### Basic usage

Plot the raw experimental and observational data.
```r
# Plot the first experiment, ensemble mean, first start year, first forecast time
exp1 <- ClimProjDiags::Subset(exp, c("dat", "var"), list(1, 1), drop = 'selected')
exp1 <- s2dv::MeanDims(exp1, "ensemble")
lats <- attr(exp, 'Variables')$system5c3s$lat
lons <- attr(exp, 'Variables')$system5c3s$lon

VizEquiMap(exp1[1, 1, , ], lon = lons, lat = lats, filled.continents = FALSE,
           toptitle = "SEAS5 near-surface temperature, Nov. 1997", 
           units = "K", bar_limits = c(250, 300), brks = 21,
           width = 8, height = 8, bar_extra_margin = c(1, 0, 1, 0),
           fileout = 'maps_equimap_raw_exp1.png')

# Plot corresponding observational data
obs1 <- ClimProjDiags::Subset(obs, c("dat", "var"), list(1, 1), drop = 'selected')
VizEquiMap(obs1[1, 1, , ], lon = lons, lat = lats, filled.continents = FALSE,
           toptitle = "ERA5 near-surface temperature, Nov. 1997", 
           units = "K", bar_limits = c(250, 300), brks = 21,
           width = 8, height = 8, bar_extra_margin = c(1, 0, 1, 0),
           fileout = 'maps_equimap_raw_obs.png')
```
<img src="./Figures/maps_equimap_raw_exp1.png" width="600" />
<img src="./Figures/maps_equimap_raw_obs.png" width="600" />

#### dots

Plot correlation with the significance by parameter `dots`. 
Use s2dv function `Corr()` to calculate the correlation. The dotted points are the insignificant ones.

```r
corr <- s2dv::Corr(exp1, obs1, time_dim = 'sdate', dat_dim = NULL, sign = TRUE,
                   conf = FALSE, pval = FALSE)
VizEquiMap(corr$corr[1, , ], lon = lons, lat = lats, filled.continents = FALSE,
           dots = !drop(corr$sign)[1, , ], dot_symbol = 3, dot_size = 1.2,
           toptitle = "Correlation of near-surface temperature, SEAS5 - ERA5, Nov. 1997", 
           title_scale = 0.7, color_fun = ClimPalette("yellowred"),
           bar_limits = c(0, 1), brks = 21,
           width = 8, height = 8, bar_extra_margin = c(1, 0, 1, 0),
           fileout = 'maps_equimap_corr_exp1_obs.png')
```

<img src="./Figures/maps_equimap_corr_exp1_obs.png" width="600" />

#### contours

To draw the contour lines, set parameter `square` as FALSE to smooth the grid borders.
The contours can be adjusted by providing a matrix to parameter `contours` with dimensions 
`c(n. of longitudes, n. of latitudes)`. The contours matrix will be drawn over the map, 
using the thresholds provided in `brks2`.

You can also plot the contours of the original data without border 
smoothing, to plot only some of the default contours, or to plot contours 
defined by another field.  

Here, we plot the same raw data as the previous section but with contours. 
```r
VizEquiMap(exp1[1, 1, , ], lon = lons, lat = lats, filled.continents = FALSE,
           square = FALSE,
           toptitle = "SEAS5 near-surface temperature, Nov. 1997", 
           units = "K", bar_limits = c(250, 300), brks = 21,
           width = 8, height = 8, bar_extra_margin = c(1, 0, 1, 0),
           fileout = 'maps_equimap_contour_raw_exp1.png')

# Adjust the styles
VizEquiMap(exp1[1, 1, , ], lon = lons, lat = lats, filled.continents = FALSE,
           square = TRUE, 
           contours = exp1[1, 1, , ], contour_lwd = 1, brks2 = seq(240, 300, 5),
           contour_color = 'blue', contour_lty = 5, contour_label_scale = 0.7,
           toptitle = "SEAS5 near-surface temperature, Nov. 1997", 
           units = "K", bar_limits = c(250, 300), brks = 21,
           width = 8, height = 8, bar_extra_margin = c(1, 0, 1, 0),
           fileout = 'maps_equimap_contour_raw_exp1_ver2.png')
```

<img src="./Figures/maps_equimap_contour_raw_exp1.png" width="600" />
<img src="./Figures/maps_equimap_contour_raw_exp1_ver2.png" width="600" />

#### Boxes

We can draw boxes on the map using parameters `boxlim`, `boxcol` and `boxlwd`.
They specify the position of the corners, color and thickness of a box to be drawn 
on the map. 

We use the same raw data from the previous section and add two boxes, 
one over Alpine region (green) and one over south side of Mediterranean Sea (yellow). 
```r
VizEquiMap(exp1[1, 1, , ], lon = lons, lat = lats, filled.continents = FALSE,
           toptitle = "SEAS5 near-surface temperature, Nov. 1997", 
           units = "K", bar_limits = c(250, 300), brks = 21,
           width = 8, height = 8, bar_extra_margin = c(1, 0, 1, 0),
           boxlim = list(c(6, 45, 15, 48), c(10, 30, 20, 36)), 
           boxcol = c('green', 'yellow'), boxlwd = c(2, 2),
           fileout = 'maps_equimap_raw_exp1_boxes.png')
```

<img src="./Figures/maps_equimap_raw_exp1_boxes.png" width="600" />


### VizStereoMap()

`VizStereoMap()` plots the map with stereographic projection. 
It can be called almost identically to `VizEquiMap()`, except
that it requires the `latlims` parameter to specify which range of latitudes to
be plotted on the stereographic projection map.  
The parameter `intlat` can set the interval in degrees between consecutive latitude circles on the plot.

Next a couple of examples:

```r
## Loading data over the entire globe
world_data <- Load('tas', list(expA, expB), list(obsX),
                    sdates = sdates[1],
                    leadtimemin = 2, leadtimemax = 13,
                    latmin = -90, latmax = 90,
                    lonmin = 0, lonmax = 360,
                    output = 'lonlat', grid = 't106grid',
                    method = 'distance-weighted')
VizStereoMap(s2dv::MeanDims(world_data$mod, 2)[1, 1, 1, , ], 
              world_data$lon, world_data$lat, c(40, 90),
              brks = 100, bar_limits = c(240, 290),
              toptitle = "Exp. A 'tas', s. date: 1990-11-01, f. time: 1 month",
              title_scale = 0.5,
              units = "K", filled.continents = 'black',
              fileout = 'vis_stereomap_raw_expA.png')

VizStereoMap(s2dv::MeanDims(world_data$obs, 2)[1, 1, 10, , ], 
              world_data$lon, world_data$lat, c(-90, -60), intlat = 10, 
              brks = 100, bar_limits = c(240, 290),
              boxlim = list(c(0, -85, 135, -70)),
              toptitle = "Obs. X 'tas', 1990-12-01",
              title_scale = 0.5,
              units = "K", fileout = 'vis_stereomap_raw_obsX.png')
```

<img src="./Figures/vis_stereomap_raw_expA.png" width="600" />
<img src="./Figures/vis_stereomap_raw_obsX.png" width="600" />

### VizAnimateMap()

`VizAnimateMap()` generates animations of maps from `VizEquiMap()` or 
`VizStereoMap()` and saves them in GIF files at the paths specified in the
parameter `fileout`. It receives an array with the dimensions:
```r
  c(n. of experiments/observations, n. of observations, 3, n. of forecast times, n. of latitudes, n. of longitudes)
```
the first 3 being optional and the 3rd dimension corresponding to the lower 
confidence interval, the actual value and the upper confidence interval. This 
means it can plot maps of a field of one or multiple experimental or 
observational datasets, averaged across ensemble members and starting dates 
(climatologies) or indices or scores computed across starting dates against 
one or more observations. The confidence intervals, if provided, are used to 
draw black dots on grid cells that reach a 95% significance level, if 
requested via `msk95lev`.

The provided data is assumed to be in a monthly frequency and to start at 
January. Otherwise it can be adjusted with `monini` and `freq`.

Whether to plot with a equidistant rectangular projection or a stereographic 
projection can be chosen with the parameter `equi`. The plot can be limited to 
a sub-region of the provided data via the parameters `lonmin`, `lonmax`, 
`latmin` and `latmax`.

`AnimateMap()` allows for the typical adjustments in the map plotting 
functions: specifying the palette colors and breaks (`col` and `brk`),
displaying or not a legend (`drawleg`, `subsampleg`), selecting a color for
the NA values (`colNA`) and filling or not the continents 
(`filled.continents`).

Further title and axis tick adjustments can be achieved with `toptitle`, 
`sizetit`, `units`, `intlon` and `intlat`.
brk col drawleg subsampleg colNA filled.continents

Next a few examples:

```r
map_clim <- s2dv::Clim(map_data$mod, map_data$obs, memb = FALSE)

cols <- ClimColors(50)

data_min <- min(map_data$mod, map_data$obs, na.rm = TRUE)
data_max <- max(map_data$mod, map_data$obs, na.rm = TRUE)
brks <- round(seq(data_min, data_max, length.out = length(cols) + 1), 2)

AnimateMap(ClimProjDiags::Subset(map_clim$exp, 'dataset', 1), 
           map_data$lon, map_data$lat, monini = 12, 
           toptitle = "Exp. A climatologies.", 
           units = "K", brks = brks, cols = cols,
           fileout = "vis_anim_clim_expA.gif")
```
<img src="./Figures/vis_anim_clim_expA.gif" width="600" />

And, as seen in [**Snippet 2**](snippets.md#snippet2), the animations of the 
actual time correlations of Experiment A and B against Observation X over the 
Atlantic, with black dots on values that reach a 95% significance level:

<img src="./Figures/snip2_anim_corr_expA_obsX.gif" width="600" />

<img src="./Figures/snip2_anim_corr_expB_obsX.gif" width="600" />

Also the entire globe and stereographic projection maps can be animated:

```r
world_clim <- s2dv::Clim(world_data$mod, world_data$obs, memb = FALSE)
AnimateMap(ClimProjDiags::Subset(world_clim$exp, 'dataset', 1), 
           world_data$lon, world_data$lat, 
           filled.continents = FALSE, monini = 12,
           toptitle = "Exp. A climatologies.", units = "K",
           brks = brks, cols = cols, 
           fileout = 'vis_anim_clim_expA_world.gif')
AnimateMap(world_clim$obs, 
           world_data$lon, world_data$lat, equi = FALSE,
           latmin = 60, latmax = 90, monini = 12,
           toptitle = "Obs. X climatologies.", 
           units = "K", brks = brks, cols = cols,
           fileout = "vis_anim_clim_obsX_world.gif")
```

<img src="./Figures/vis_anim_clim_expA_world.gif" width="600" />

<img src="./Figures/vis_anim_clim_obsX_world.gif" width="600" />

### VizLayout()

This function allows to easily combine plots from any R plot function in 
layouts. The input data can be provided in multiple data arrays, and a common
colour bar can be set for the multi-panel.

A common use case is to plot the ensemble members at a given time step:

```r
VizLayout(VizEquiMap, c('lat', 'lon'),
           ClimProjDiags::Subset(map_data$mod, 
                  list('dataset', 'sdate', 'ftime'), 
                  list(1, 1, 1)), 
           map_data$lon, map_data$lat, units = 'K',
           toptitle = "Exp. A 'tas', s. date: 1990-11-01, f.time: 1 month",
           titles = paste("Member", 1:dim(map_data$mod)[2]),
           brks = 50, bar_limits = c(250, 300), coast_color = 'black',
           fileout = "vis_layout_equimap_expA.png") 
```

<img src="./Figures/vis_layout_equimap_expA.png" width="600" />

But really complex layouts can be achieved thanks to the great number of
available parameters:

```r
ens_mean <- ClimProjDiags::Subset(world_data$mod, 
                   list('dataset', 'sdate', 'ftime'), 
                   list(1, 1, 1))
layout <- VizLayout(fun = c('VizEquiMap', 'plot', 'plot', 'VizStereoMap'),
                     plot_dims = c('lat', 'lon'), 
                     var = list(ens_mean, array(1:10), 
                                array(10:1), ens_mean), 
                     lon = world_data$lon, lat = world_data$lat, 
                     fill = 'black', sizetit = 0.5, axes_label_scale = 0.6, 
                     coast_color = 'yellow',
                     titles = paste('Fig.', 1:12), toptitle = 'Multipanel', 
                     row_titles = paste('Row', 1:3), col_titles = paste('Col', 1:4), 
                     drawleg = 'E', units = 'K', units_scale = 2, 
                     bar_limits = c(275, 300), brks = 26, 
                     bar_extra_labels = 281:284, 
                     width = 12, height = 10, res = 200, 
                     fileout = 'vis_layout_complex.png')
```

<img src="./Figures/vis_layout_complex.png" width="800" />

### VizSection()

WIP.
