---
title: "Map: Stereographic Projection"
author: "An-Chi Ho"
date: "2023-11-16"
output: html_document
vignette: >
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteIndexEntry{Map: Stereographic Projection}
  %\usepackage[utf8]{inputenc}
---

We will use the data loaded in [Data Loading](data_loading.md) in this vignette. 
Please follow that vignette first to get the data if you want to replicate the results in this vignette. Load global data with `region = "global"` in the loading script.

# Map plotting

In this vignette, we will use the following functions that plot stereographi projection
map: 
`VizStereoMap()`, `VizAnimateMap()`, `VizRobinson()`, `VizLayout()`.

## VizStereoMap()

`VizStereoMap()` plots the map with stereographic projection.
The latitude range needs to be within 110 degrees, being speficied by parameter `latlims`.
The parameter `intlat` can set the interval in degrees between consecutive latitude circles on the plot. See more parameters in function documentation.

We plot the climatology ensemble-mean SEAS5 near-surface temperature data by VizStereoMap(), one with North Pole as center and the other with South Pole as center.

We can add boxes in the map by giving parameter `boxlim`.

```r
exp1 <- ClimProjDiags::Subset(exp, c("dat", "var"), list(1, 1), drop = "selected")
exp1_clim <- s2dv::MeanDims(exp1, c("sdate", "ensemble"), na.rm = TRUE)

lats <- attributes(exp)$Variables$system5c3s$lat
lons <- attributes(exp)$Variables$system5c3s$lon
lats_np_ind <- which(lats %in% 60:90)
lats_sp_ind <- which(lats %in% -90:-60)

cols <- ClimColors(50)
col_inf <- cols[1]
col_sup <- tail(cols, 1)
cols <- cols[c(2:49)]
brks_range <- range(exp1_clim[c(lats_np_ind, lats_sp_ind)], na.rm = TRUE)
brks <- round(seq(ceiling(brks_range[1]), floor(brks_range[2]),
                  length.out = 49), 1)
                  
VizStereoMap(exp1_clim[1, lats_np_ind, ], latlims = c(60, 90),
             lon = lons, lat = lats[lats_np_ind],
              brks = brks, cols = cols, col_sup = col_sup,
              toptitle = "SEAS5 tas climatology (Nov. 2011-2016), ftime = 1, North Pole",
              title_scale = 0.45,
              units = "K", filled.continents = FALSE,
              fileout = 'map_stereo_clim_exp1_np.png')

VizStereoMap(exp1_clim[1, lats_sp_ind, ], latlims = c(-90, -60),
             lon = lons, lat = lats[lats_sp_ind],
             brks = brks, cols = cols,
             toptitle = "SEAS5 tas climatology (Nov. 011-2016), ftime = 1, South Pole",
             title_scale = 0.45, boxlwd = 2,
             boxlim = list(c(166, -85, 235, -77)),
             units = "K", filled.continents = FALSE,
             fileout = 'map_stereo_clim_exp1_sp.png')
```

<img src="./Figures/map_stereo_clim_exp1_np.png" width="600" />
<img src="./Figures/map_stereo_clim_exp1_sp.png" 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(VizStereoMap, c('lat', 'lon'), exp1_clim[, lats_np_ind, ],
           lon = lons, lat = lats[lats_np_ind],
           brks = brks, cols = cols, col_sup = col_sup,
           bar_extra_margin = c(1, 0, 1, 0),
           units = 'K', filled.continents = FALSE, title_scale = 0.7,
           toptitle = "SEAS5 tas climatology (Nov. 2011-2016), North Pole",
           titles = paste("ftime", 1:dim(exp1_clim)[1]),
           fileout = "map_stereo_layout_clim_exp1_np.png") 
```
<img src="./Figures/map_stereo_layout_clim_exp1_np.png" width="600" />


## VizAnimateMap()

`VizAnimateMap()` can generate animation with the plots generated by `VizStereoMap()`. The input array should have dimensions as follow: 
```r
  c(n. of experiments/observations, n. of observations, 3, n. of forecast times, n. of latitudes, n. of longitudes)
```
The first 3 dimensions are optional; the 3rd dimension corresponding to the lower 
confidence interval, the actual value and the upper confidence interval. 
The confidence intervals, if provided, are drawn with
black dots on grid cells where reach 95% significance level, if requested via `msk95lev`.

The data is assumed to be monthly frequency and to start in
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`.
Check function documentation for more explanations of function arguments.

We plot the climatology ensemble-mean SEAS5 tas and animate through forecast time.

```r
VizAnimateMap(exp1_clim, equi = FALSE,
              lon = lons, lat = lats,
              latmin = 60, latmax = 90, 
              filled.continents = FALSE, monini = 11,
              toptitle = "SEAS5 tas climatology (Nov. 2011-2016), North Pole",
              brks = brks, cols = cols, col_sup = col_sup, triangle_ends = c(F, T), 
              units = "K", sizetit = 0.5,
              fileout = 'map_stereo_anim_clim_exp1_np.gif')

```

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

## VizRobinson()

VizRobinson() can plot various projection types, including stereographic projection. Use `target_proj = 3995` (Arctic Polar Stereographic -- EPSG:3995) to assign the projection type. Note that different PROJ and GDAL module versions may have different CRS codes.

We use VizRobinson() to plot the same figure as the first one, climatology ensemble-mean SEAS5 tas at North Pole.

```r
VizRobinson(exp1_clim[1, lats_np_ind, ],  target_proj = 3995,
            lon = lons, lat = lats[lats_np_ind],
            brks = brks, cols = cols, col_sup = col_sup,
            legend = 's2dv', style = 'polygon',
            toptitle = "SEAS5 tas climatology (Nov. 2011-2016), ftime = 1, North Pole",
            caption = paste0("plotted by esviz::VizRobinson"),
            units = "K", title_size = 14,
            width = 8, height = 8,
            fileout = "map_stereo_clim_exp1_np_robin.png")
```
<img src="./Figures/map_stereo_clim_exp1_np_robin.png" width="600" />
