{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Plotting Tiles\n", "\n", "## Objectives\n", "\n", "Introduce several different methods for plotting ECCO v4 fields that are stored as tiles in `Datasets` or `DataArrays`. Emphasis is placed on fields stored on the ECCO v4 native llc90 grid and loaded from NetCDF tile files.\n", "\n", "## Introduction\n", "\n", "*\"Over the years many different plotting modules and packages have been developed for Python. For most of that time there was no clear favorite package, but recently matplotlib has become the most widely used. Nevertheless, many of the others are still available and may suit your tastes or needs better. Some of these are interfaces to existing plotting libraries while others are Python-centered new implementations.*\n", "-- from : https://wiki.python.org/moin/NumericAndScientific/Plotting\n", "\n", "\n", "The link above profiles a long list of Python tools for plotting. In this tutorial we use just two libraries, *matplotlib* and *Cartopy*.\n", "\n", "> Note: In this tutorial you will need monthly SSH, THETA, and SALT for the year 2000. The ShortNames of the datasets needed are **ECCO_L4_SSH_LLC0090GRID_MONTHLY_V4R4** and **ECCO_L4_TEMP_SALINITY_LLC0090GRID_MONTHLY_V4R4**. You will also need the [grid file](https://ecco-v4-python-tutorial.readthedocs.io/ECCO_v4_Loading_the_ECCOv4_native_model_grid_parameters.html). The `ecco_access` [Python package](https://ecco-access.readthedocs.io) used in the notebook will handle download or retrieval of the necessary data.\n", "\n", "### matplotlib\n", "*\"Matplotlib is a Python 2D plotting library which produces publication quality figures in a variety of hardcopy formats and interactive environments across platforms. Matplotlib can be used in Python scripts, the Python and IPython shell, the jupyter notebook, web application servers, and four graphical user interface toolkits.\"*\n", "\n", "*\"For simple plotting the pyplot module provides a MATLAB-like interface, particularly when combined with [Juypter Notebooks]. For the power user, you have full control of line styles, font properties, axes properties, etc, via an object oriented interface or via a set of functions familiar to MATLAB users.\"*\n", "-- from https://matplotlib.org/index.html\n", "\n", "Matplotlib and pyplot even have a tutorial: https://matplotlib.org/users/pyplot_tutorial.html\n", "\n", "### Cartopy\n", "\n", "\"Cartopy is a Python package designed for geospatial data processing in order to produce maps and other geospatial data analyses.\"\n", "\n", "Cartopy makes use of the powerful PROJ.4, NumPy and Shapely libraries and includes a programmatic interface built on top of Matplotlib for the creation of publication quality maps.\n", "\n", "Key features of cartopy are its object oriented projection definitions, and its ability to transform points, lines, vectors, polygons and images between those projections.\n", "\n", "You will find cartopy especially useful for large area / small scale data, where Cartesian assumptions of spherical data traditionally break down. If you’ve ever experienced a singularity at the pole or a cut-off at the dateline, it is likely you will appreciate cartopy’s unique features!\"*\n", "\n", "-- from https://scitools.org.uk/cartopy/docs/latest/\n", "\n", "\n", "## The default orientation of the lat-lon-cap tile fields\n", "\n", "Before we begin plotting ECCOv4 fields on the native llc90 model grid we are reminded how how the 13 tiles are oriented with respect to their \"local\" **x** and **y** and with respect to each other.\n", "\n", "\n", "\n", "Tiles 7-12 are rotated 90 degrees counter-clockwise relative to tiles 0-5.\n", "\n", "> **Note:** *The rotated orientation of tiles 7-12 presents some complications but don't panic! The good news is that you don't need to reorient tiles to plot them.*\n", "\n", "## Plotting single tiles using ``imshow``, ``pcolormesh``, and ``contourf``\n", "\n", "First, let's load the all 13 tiles for sea surface height and the model grid parameters.\n", "\n", "> **Note:** The notebook uses the `ecco_access` package to download (or directly access in the AWS Cloud) the ECCO output; you may need to [install it](https://ecco-access.readthedocs.io/en/latest/Installation.html)." ] }, { "cell_type": "code", "execution_count": 1, "metadata": {}, "outputs": [], "source": [ "import numpy as np\n", "import sys\n", "import xarray as xr\n", "from os.path import join,expanduser\n", "import matplotlib.pyplot as plt\n", "%matplotlib inline\n", "import glob\n", "import warnings\n", "warnings.filterwarnings('ignore')\n", "\n", "\n", "import ecco_v4_py as ecco\n", "import ecco_access as ea\n", "\n", "\n", "# are you working in the AWS Cloud?\n", "incloud_access = False\n", "\n", "# indicate mode of access from PO.DAAC\n", "# options are:\n", "# 'download': direct download from internet to your local machine\n", "# 'download_ifspace': like download, but only proceeds \n", "# if your machine have sufficient storage\n", "# 's3_open': access datasets in-cloud from an AWS instance\n", "# 's3_open_fsspec': use jsons generated with fsspec and \n", "# kerchunk libraries to speed up in-cloud access\n", "# 's3_get': direct download from S3 in-cloud to an AWS instance\n", "# 's3_get_ifspace': like s3_get, but only proceeds if your instance \n", "# has sufficient storage\n", "user_home_dir = expanduser('~')\n", "download_dir = join(user_home_dir,'Downloads','ECCO_V4r4_PODAAC')\n", "if incloud_access:\n", " access_mode = 's3_open_fsspec'\n", " download_root_dir = None\n", " jsons_root_dir = join(user_home_dir,'MZZ')\n", "else:\n", " access_mode = 'download_ifspace'\n", " download_root_dir = download_dir\n", " jsons_root_dir = None" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [], "source": [ "# load some useful cartopy routines\n", "from cartopy import config\n", "import cartopy.crs as ccrs\n", "import cartopy.feature as cfeature\n", "\n", "# and a new matplotlib routine \n", "import matplotlib.path as mpath" ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Size of files to be downloaded to instance is 0.268 GB,\n", "which is 0.19% of the 144.102 GB available storage.\n", "Proceeding with file downloads via NASA Earthdata URLs\n", "DL Progress: 100%|###########################| 1/1 [00:02<00:00, 2.47s/it]\n", "\n", "=====================================\n", "total downloaded: 8.57 Mb\n", "avg download speed: 3.47 Mb/s\n", "Time spent = 2.471755266189575 seconds\n", "\n", "\n", "DL Progress: 100%|#########################| 12/12 [00:05<00:00, 2.05it/s]\n", "\n", "=====================================\n", "total downloaded: 71.01 Mb\n", "avg download speed: 12.11 Mb/s\n", "Time spent = 5.8622353076934814 seconds\n", "\n", "\n", "DL Progress: 100%|#########################| 12/12 [00:04<00:00, 2.72it/s]\n", "\n", "=====================================\n", "total downloaded: 208.38 Mb\n", "avg download speed: 47.05 Mb/s\n", "Time spent = 4.429197311401367 seconds\n", "\n", "\n" ] } ], "source": [ "## open ECCO datasets needed for the tutorial\n", "\n", "ShortNames_list = [\"ECCO_L4_GEOMETRY_LLC0090GRID_V4R4\",\\\n", " \"ECCO_L4_SSH_LLC0090GRID_MONTHLY_V4R4\",\\\n", " \"ECCO_L4_TEMP_SALINITY_LLC0090GRID_MONTHLY_V4R4\"]\n", "\n", "ds_dict = ea.ecco_podaac_to_xrdataset(ShortNames_list,\\\n", " StartDate='2000-01',EndDate='2000-12',\\\n", " mode=access_mode,\\\n", " download_root_dir=download_root_dir,\\\n", " jsons_root_dir=jsons_root_dir,\\\n", " max_avail_frac=0.5)\n", "\n", "ecco_grid = ds_dict[ShortNames_list[0]]\n", "ds_SSH = ds_dict[ShortNames_list[1]]\n", "ds_temp_sal = ds_dict[ShortNames_list[2]]\n", "\n", "## select only *surface* temperature and salinity (SST and SSS)\n", "ds_SST_SSS = ds_temp_sal.isel(k=0)\n", "\n", "\n", "## Copy ecco_ds from ecco_grid dataset\n", "ecco_ds = ecco_grid.copy()\n", "## Add SSH, SST, and SSS variables to ecco_ds\n", "ecco_ds['SSH'] = ds_SSH['SSH']\n", "ecco_ds['SST'] = ds_SST_SSS['THETA']\n", "ecco_ds['SSS'] = ds_SST_SSS['SALT']\n", "\n", "## Load ecco_ds into memory\n", "ecco_ds = ecco_ds.compute()" ] }, { "cell_type": "code", "execution_count": 6, "metadata": {}, "outputs": [ { "data": { "text/html": [ "
<xarray.Dataset> Size: 104MB\n",
"Dimensions: (i: 90, i_g: 90, j: 90, j_g: 90, k: 50, k_u: 50, k_l: 50,\n",
" k_p1: 51, tile: 13, nb: 4, nv: 2, time: 12)\n",
"Coordinates: (12/21)\n",
" * i (i) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * i_g (i_g) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j (j) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * j_g (j_g) int32 360B 0 1 2 3 4 5 6 7 8 9 ... 81 82 83 84 85 86 87 88 89\n",
" * k (k) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" * k_u (k_u) int32 200B 0 1 2 3 4 5 6 7 8 9 ... 41 42 43 44 45 46 47 48 49\n",
" ... ...\n",
" Zu (k_u) float32 200B -10.0 -20.0 -30.0 ... -5.678e+03 -6.134e+03\n",
" Zl (k_l) float32 200B 0.0 -10.0 -20.0 ... -5.244e+03 -5.678e+03\n",
" XC_bnds (tile, j, i, nb) float32 2MB -115.0 -115.0 -107.9 ... -115.0 -108.5\n",
" YC_bnds (tile, j, i, nb) float32 2MB -88.18 -88.32 -88.3 ... -88.18 -88.16\n",
" Z_bnds (k, nv) float32 400B 0.0 -10.0 -10.0 ... -5.678e+03 -6.134e+03\n",
" * time (time) datetime64[ns] 96B 2000-01-16T12:00:00 ... 2000-12-16T12:...\n",
"Dimensions without coordinates: nb, nv\n",
"Data variables: (12/24)\n",
" CS (tile, j, i) float32 421kB 0.06158 0.06675 ... -0.9854 -0.9984\n",
" SN (tile, j, i) float32 421kB -0.9981 -0.9978 ... -0.1705 -0.05718\n",
" rA (tile, j, i) float32 421kB 3.623e+08 3.633e+08 ... 3.611e+08\n",
" dxG (tile, j_g, i) float32 421kB 1.558e+04 1.559e+04 ... 2.314e+04\n",
" dyG (tile, j, i_g) float32 421kB 2.321e+04 2.327e+04 ... 1.558e+04\n",
" Depth (tile, j, i) float32 421kB 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0\n",
" ... ...\n",
" maskC (k, tile, j, i) bool 5MB False False False ... False False False\n",
" maskW (k, tile, j, i_g) bool 5MB False False False ... False False False\n",
" maskS (k, tile, j_g, i) bool 5MB False False False ... False False False\n",
" SSH (time, tile, j, i) float32 5MB nan nan nan nan ... nan nan nan nan\n",
" SST (time, tile, j, i) float32 5MB nan nan nan nan ... nan nan nan nan\n",
" SSS (time, tile, j, i) float32 5MB nan nan nan nan ... nan nan nan nan\n",
"Attributes: (12/58)\n",
" acknowledgement: This research was carried out by the Jet...\n",
" author: Ian Fenty and Ou Wang\n",
" cdm_data_type: Grid\n",
" comment: Fields provided on the curvilinear lat-l...\n",
" Conventions: CF-1.8, ACDD-1.3\n",
" coordinates_comment: Note: the global 'coordinates' attribute...\n",
" ... ...\n",
" references: ECCO Consortium, Fukumori, I., Wang, O.,...\n",
" source: The ECCO V4r4 state estimate was produce...\n",
" standard_name_vocabulary: NetCDF Climate and Forecast (CF) Metadat...\n",
" summary: This dataset provides geometric paramete...\n",
" title: ECCO Geometry Parameters for the Lat-Lon...\n",
" uuid: 87ff7d24-86e5-11eb-9c5f-f8f21e2ee3e0