Making a simple map of a variable
Overview
Take the data we read in in the previous notebook, and learn how to make a simple map of a few different variables.
Spin up a Dask cluster and load the data
Super quick plot
Two nicer plots on a map projection
Prerequisites
Concepts |
Importance |
Notes |
---|---|---|
Necessary |
||
Necessary |
||
Helpful |
||
Helpful |
Time to learn: 10 min
Imports
import xarray as xr
from dask.distributed import LocalCluster
import glob
import numpy as np
import matplotlib.pyplot as plt
import cartopy
import cartopy.crs as ccrs
import pop_tools
import s3fs
import netCDF4
from module import adjust_pop_grid
from display_source import display_source
Connect to cluster
Since we’re doing a little more processing in this notebook, we spin up a local Dask cluster. See the Dask Cookbook or Dask tutorial to learn more about this!
cluster = LocalCluster()
client = cluster.get_client()
Load the data
jetstream_url = 'https://js2.jetstream-cloud.org:8001/'
s3 = s3fs.S3FileSystem(anon=True, client_kwargs=dict(endpoint_url=jetstream_url))
# Generate a list of all files in CESM folder
s3path = 's3://pythia/ocean-bgc/cesm/g.e22.GOMIPECOIAF_JRA-1p4-2018.TL319_g17.4p2z.002branch/ocn/proc/tseries/month_1/*'
remote_files = s3.glob(s3path)
# Open all files from folder
fileset = [s3.open(file) for file in remote_files]
# Open with xarray
ds = xr.open_mfdataset(fileset, data_vars="minimal", coords='minimal', compat="override", parallel=True,
drop_variables=["transport_components", "transport_regions", 'moc_components'], decode_times=True)
ds
<xarray.Dataset> Size: 28GB Dimensions: (nlat: 384, nlon: 320, time: 120, z_t: 60, z_t_150m: 15) Coordinates: TLAT (nlat, nlon) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray> TLONG (nlat, nlon) float64 983kB dask.array<chunksize=(384, 320), meta=np.ndarray> * time (time) object 960B 2010-01-16 12:00:00 ..... * z_t (z_t) float32 240B 500.0 ... 5.375e+05 * z_t_150m (z_t_150m) float32 60B 500.0 ... 1.45e+04 Dimensions without coordinates: nlat, nlon Data variables: (12/45) FG_CO2 (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray> Fe (time, z_t, nlat, nlon) float32 4GB dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray> NO3 (time, z_t, nlat, nlon) float32 4GB dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray> PO4 (time, z_t, nlat, nlon) float32 4GB dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray> POC_FLUX_100m (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray> SALT (time, z_t, nlat, nlon) float32 4GB dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray> ... ... sp_Fe_lim_Cweight_avg_100m (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray> sp_Fe_lim_surf (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray> sp_N_lim_Cweight_avg_100m (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray> sp_N_lim_surf (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray> sp_P_lim_Cweight_avg_100m (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray> sp_P_lim_surf (time, nlat, nlon) float32 59MB dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- nlat: 384
- nlon: 320
- time: 120
- z_t: 60
- z_t_150m: 15
- TLAT(nlat, nlon)float64dask.array<chunksize=(384, 320), meta=np.ndarray>
- long_name :
- array of t-grid latitudes
- units :
- degrees_north
Array Chunk Bytes 0.94 MiB 0.94 MiB Shape (384, 320) (384, 320) Dask graph 1 chunks in 2 graph layers Data type float64 numpy.ndarray - TLONG(nlat, nlon)float64dask.array<chunksize=(384, 320), meta=np.ndarray>
- long_name :
- array of t-grid longitudes
- units :
- degrees_east
Array Chunk Bytes 0.94 MiB 0.94 MiB Shape (384, 320) (384, 320) Dask graph 1 chunks in 2 graph layers Data type float64 numpy.ndarray - time(time)object2010-01-16 12:00:00 ... 2019-12-...
array([cftime.DatetimeNoLeap(2010, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2010, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2011, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2012, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2013, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2014, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2015, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2016, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2017, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2018, 12, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 1, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 2, 15, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 3, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 4, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 5, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 6, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 7, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 8, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 9, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 10, 16, 12, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 11, 16, 0, 0, 0, 0, has_year_zero=True), cftime.DatetimeNoLeap(2019, 12, 16, 12, 0, 0, 0, has_year_zero=True)], dtype=object)
- z_t(z_t)float32500.0 1.5e+03 ... 5.375e+05
- long_name :
- depth from surface to midpoint of layer
- units :
- centimeters
- positive :
- down
- valid_min :
- 500.0
- valid_max :
- 537500.0
array([5.000000e+02, 1.500000e+03, 2.500000e+03, 3.500000e+03, 4.500000e+03, 5.500000e+03, 6.500000e+03, 7.500000e+03, 8.500000e+03, 9.500000e+03, 1.050000e+04, 1.150000e+04, 1.250000e+04, 1.350000e+04, 1.450000e+04, 1.550000e+04, 1.650984e+04, 1.754790e+04, 1.862913e+04, 1.976603e+04, 2.097114e+04, 2.225783e+04, 2.364088e+04, 2.513702e+04, 2.676542e+04, 2.854837e+04, 3.051192e+04, 3.268680e+04, 3.510935e+04, 3.782276e+04, 4.087846e+04, 4.433777e+04, 4.827367e+04, 5.277280e+04, 5.793729e+04, 6.388626e+04, 7.075633e+04, 7.870025e+04, 8.788252e+04, 9.847059e+04, 1.106204e+05, 1.244567e+05, 1.400497e+05, 1.573946e+05, 1.764003e+05, 1.968944e+05, 2.186457e+05, 2.413972e+05, 2.649001e+05, 2.889385e+05, 3.133405e+05, 3.379793e+05, 3.627670e+05, 3.876452e+05, 4.125768e+05, 4.375392e+05, 4.625190e+05, 4.875083e+05, 5.125028e+05, 5.375000e+05], dtype=float32)
- z_t_150m(z_t_150m)float32500.0 1.5e+03 ... 1.35e+04 1.45e+04
- long_name :
- depth from surface to midpoint of layer
- units :
- centimeters
- positive :
- down
- valid_min :
- 500.0
- valid_max :
- 14500.0
array([ 500., 1500., 2500., 3500., 4500., 5500., 6500., 7500., 8500., 9500., 10500., 11500., 12500., 13500., 14500.], dtype=float32)
- FG_CO2(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- DIC Surface Gas Flux
- units :
- mmol/m^3 cm/s
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - Fe(time, z_t, nlat, nlon)float32dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray>
- long_name :
- Dissolved Inorganic Iron
- units :
- mmol/m^3
- grid_loc :
- 3111
- cell_methods :
- time: mean
Array Chunk Bytes 3.30 GiB 13.18 MiB Shape (120, 60, 384, 320) (30, 15, 96, 80) Dask graph 256 chunks in 2 graph layers Data type float32 numpy.ndarray - NO3(time, z_t, nlat, nlon)float32dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray>
- long_name :
- Dissolved Inorganic Nitrate
- units :
- mmol/m^3
- grid_loc :
- 3111
- cell_methods :
- time: mean
Array Chunk Bytes 3.30 GiB 13.18 MiB Shape (120, 60, 384, 320) (30, 15, 96, 80) Dask graph 256 chunks in 2 graph layers Data type float32 numpy.ndarray - PO4(time, z_t, nlat, nlon)float32dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray>
- long_name :
- Dissolved Inorganic Phosphate
- units :
- mmol/m^3
- grid_loc :
- 3111
- cell_methods :
- time: mean
Array Chunk Bytes 3.30 GiB 13.18 MiB Shape (120, 60, 384, 320) (30, 15, 96, 80) Dask graph 256 chunks in 2 graph layers Data type float32 numpy.ndarray - POC_FLUX_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- POC Flux at 100m
- units :
- mmol/m^3 cm/s
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - SALT(time, z_t, nlat, nlon)float32dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray>
- long_name :
- Salinity
- units :
- gram/kilogram
- grid_loc :
- 3111
- cell_methods :
- time: mean
Array Chunk Bytes 3.30 GiB 13.18 MiB Shape (120, 60, 384, 320) (30, 15, 96, 80) Dask graph 256 chunks in 2 graph layers Data type float32 numpy.ndarray - SiO3(time, z_t, nlat, nlon)float32dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray>
- long_name :
- Dissolved Inorganic Silicate
- units :
- mmol/m^3
- grid_loc :
- 3111
- cell_methods :
- time: mean
Array Chunk Bytes 3.30 GiB 13.18 MiB Shape (120, 60, 384, 320) (30, 15, 96, 80) Dask graph 256 chunks in 2 graph layers Data type float32 numpy.ndarray - TEMP(time, z_t, nlat, nlon)float32dask.array<chunksize=(30, 15, 96, 80), meta=np.ndarray>
- long_name :
- Potential Temperature
- units :
- degC
- grid_loc :
- 3111
- cell_methods :
- time: mean
Array Chunk Bytes 3.30 GiB 13.18 MiB Shape (120, 60, 384, 320) (30, 15, 96, 80) Dask graph 256 chunks in 2 graph layers Data type float32 numpy.ndarray - coccoC(time, z_t_150m, nlat, nlon)float32dask.array<chunksize=(40, 5, 128, 107), meta=np.ndarray>
- long_name :
- Coccolithophores Carbon
- units :
- mmol/m^3
- grid_loc :
- 3114
- cell_methods :
- time: mean
Array Chunk Bytes 843.75 MiB 10.45 MiB Shape (120, 15, 384, 320) (40, 5, 128, 107) Dask graph 81 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_C_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores C Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_C_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores C Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_Fe_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores Fe Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_Fe_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores Fe Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_N_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores N Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_N_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores N Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_P_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores P Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - cocco_P_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores P Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diatC(time, z_t_150m, nlat, nlon)float32dask.array<chunksize=(40, 5, 128, 107), meta=np.ndarray>
- long_name :
- Diatom Carbon
- units :
- mmol/m^3
- grid_loc :
- 3114
- cell_methods :
- time: mean
Array Chunk Bytes 843.75 MiB 10.45 MiB Shape (120, 15, 384, 320) (40, 5, 128, 107) Dask graph 81 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_Fe_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom Fe Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_Fe_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom Fe Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_N_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom N Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_N_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom N Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_P_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom P Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_P_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom P Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_SiO3_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom SiO3 Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diat_SiO3_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom SiO3 Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diazC(time, z_t_150m, nlat, nlon)float32dask.array<chunksize=(40, 5, 128, 107), meta=np.ndarray>
- long_name :
- Diazotroph Carbon
- units :
- mmol/m^3
- grid_loc :
- 3114
- cell_methods :
- time: mean
Array Chunk Bytes 843.75 MiB 10.45 MiB Shape (120, 15, 384, 320) (40, 5, 128, 107) Dask graph 81 chunks in 2 graph layers Data type float32 numpy.ndarray - diaz_Fe_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diazotroph Fe Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diaz_Fe_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diazotroph Fe Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diaz_P_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diazotroph P Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - diaz_P_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diazotroph P Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - mesozooC(time, z_t_150m, nlat, nlon)float32dask.array<chunksize=(40, 5, 128, 107), meta=np.ndarray>
- long_name :
- Mesozooplankton Carbon
- units :
- mmol/m^3
- grid_loc :
- 3114
- cell_methods :
- time: mean
Array Chunk Bytes 843.75 MiB 10.45 MiB Shape (120, 15, 384, 320) (40, 5, 128, 107) Dask graph 81 chunks in 2 graph layers Data type float32 numpy.ndarray - microzooC(time, z_t_150m, nlat, nlon)float32dask.array<chunksize=(40, 5, 128, 107), meta=np.ndarray>
- long_name :
- Microzooplankton Carbon
- units :
- mmol/m^3
- grid_loc :
- 3114
- cell_methods :
- time: mean
Array Chunk Bytes 843.75 MiB 10.45 MiB Shape (120, 15, 384, 320) (40, 5, 128, 107) Dask graph 81 chunks in 2 graph layers Data type float32 numpy.ndarray - photoC_TOT_zint(time, nlat, nlon)float32dask.array<chunksize=(120, 384, 320), meta=np.ndarray>
- long_name :
- Total C Fixation Vertical Integral
- units :
- mmol/m^3 cm/s
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 56.25 MiB Shape (120, 384, 320) (120, 384, 320) Dask graph 1 chunks in 2 graph layers Data type float32 numpy.ndarray - photoC_cocco_zint(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Coccolithophores C Fixation Vertical Integral
- units :
- mmol/m^3 cm/s
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - photoC_diat_zint(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diatom C Fixation Vertical Integral
- units :
- mmol/m^3 cm/s
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - photoC_diaz_zint(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Diazotroph C Fixation Vertical Integral
- units :
- mmol/m^3 cm/s
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - photoC_sp_zint(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Small Phyto C Fixation Vertical Integral
- units :
- mmol/m^3 cm/s
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - spC(time, z_t_150m, nlat, nlon)float32dask.array<chunksize=(40, 5, 128, 107), meta=np.ndarray>
- long_name :
- Small Phyto Carbon
- units :
- mmol/m^3
- grid_loc :
- 3114
- cell_methods :
- time: mean
Array Chunk Bytes 843.75 MiB 10.45 MiB Shape (120, 15, 384, 320) (40, 5, 128, 107) Dask graph 81 chunks in 2 graph layers Data type float32 numpy.ndarray - sp_Fe_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Small Phyto Fe Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - sp_Fe_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Small Phyto Fe Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - sp_N_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Small Phyto N Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - sp_N_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Small Phyto N Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - sp_P_lim_Cweight_avg_100m(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Small Phyto P Limitation, carbon biomass weighted average over 0-100m
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray - sp_P_lim_surf(time, nlat, nlon)float32dask.array<chunksize=(60, 192, 160), meta=np.ndarray>
- long_name :
- Small Phyto P Limitation, Surface
- units :
- 1
- grid_loc :
- 2110
- cell_methods :
- time: mean
Array Chunk Bytes 56.25 MiB 7.03 MiB Shape (120, 384, 320) (60, 192, 160) Dask graph 8 chunks in 2 graph layers Data type float32 numpy.ndarray
- timePandasIndex
PandasIndex(CFTimeIndex([2010-01-16 12:00:00, 2010-02-15 00:00:00, 2010-03-16 12:00:00, 2010-04-16 00:00:00, 2010-05-16 12:00:00, 2010-06-16 00:00:00, 2010-07-16 12:00:00, 2010-08-16 12:00:00, 2010-09-16 00:00:00, 2010-10-16 12:00:00, ... 2019-03-16 12:00:00, 2019-04-16 00:00:00, 2019-05-16 12:00:00, 2019-06-16 00:00:00, 2019-07-16 12:00:00, 2019-08-16 12:00:00, 2019-09-16 00:00:00, 2019-10-16 12:00:00, 2019-11-16 00:00:00, 2019-12-16 12:00:00], dtype='object', length=120, calendar='noleap', freq=None))
- z_tPandasIndex
PandasIndex(Index([ 500.0, 1500.0, 2500.0, 3500.0, 4500.0, 5500.0, 6500.0, 7500.0, 8500.0, 9500.0, 10500.0, 11500.0, 12500.0, 13500.0, 14500.0, 15500.0, 16509.83984375, 17547.904296875, 18629.126953125, 19766.02734375, 20971.138671875, 22257.828125, 23640.8828125, 25137.015625, 26765.419921875, 28548.365234375, 30511.921875, 32686.798828125, 35109.34765625, 37822.76171875, 40878.46484375, 44337.76953125, 48273.671875, 52772.80078125, 57937.2890625, 63886.26171875, 70756.328125, 78700.25, 87882.5234375, 98470.5859375, 110620.421875, 124456.6875, 140049.71875, 157394.640625, 176400.328125, 196894.421875, 218645.65625, 241397.15625, 264900.125, 288938.46875, 313340.46875, 337979.34375, 362767.03125, 387645.1875, 412576.8125, 437539.25, 462519.03125, 487508.34375, 512502.8125, 537500.0], dtype='float32', name='z_t'))
- z_t_150mPandasIndex
PandasIndex(Index([ 500.0, 1500.0, 2500.0, 3500.0, 4500.0, 5500.0, 6500.0, 7500.0, 8500.0, 9500.0, 10500.0, 11500.0, 12500.0, 13500.0, 14500.0], dtype='float32', name='z_t_150m'))
Super quick plot
We use xarray’s isel()
(select by index) function to grab the first entry in time and vertical coordinate available in our data set. Note that our dataset has some metadata associated with it, so xarray knows that the units are in degrees Celsius without us manually specifying. Xarray’s plot()
function is great for looking at data quickly to make sure things look right before diving into more involved analysis or plotting.
We arbitrarily choose to plot temperature, but there are lots of options for variables to plot!
ds["TEMP"].isel(time=0, z_t=0).plot()
/home/runner/miniconda3/envs/ocean-bgc-cookbook-dev/lib/python3.12/site-packages/distributed/client.py:3362: UserWarning: Sending large graph of size 10.01 MiB.
This may cause some slowdown.
Consider loading the data with Dask directly
or using futures or delayed objects to embed the data into the graph without repetition.
See also https://docs.dask.org/en/stable/best-practices.html#load-data-with-dask for more information.
warnings.warn(
<matplotlib.collections.QuadMesh at 0x7fef61fae4b0>
Making a plot on a nicer map projection
Bringing in some POP grid tools
This version of CESM uses POP2 (the Parallel Ocean Program) as its ocean model. All of the ocean variable output is on the POP grid, which requires some extra wrangling to get it to work properly with standard mapping utilities.
ds_grid = pop_tools.get_grid('POP_gx1v7')
lons = ds_grid.TLONG
lats = ds_grid.TLAT
depths = ds_grid.z_t * 0.01
In this Cookbook, we have written a function for adjusting the POP2 grid. For better code reuse, we have moved this code into a module called module.py
that is imported into every notebook within this Cookbook. The content of module.py
is:
display_source(adjust_pop_grid)
def adjust_pop_grid(tlon,tlat,field):
"""
Adjusts the grid of longitude and latitude values, along with the corresponding field data.
Parameters
----------
tlon : numpy.ndarray
2D array of longitude values.
tlat : numpy.ndarray
2D array of latitude values.
field : numpy.ma.MaskedArray
2D array of field data (e.g., temperature, salinity) corresponding to the tlon and tlat arrays.
Returns
-------
lon : numpy.ndarray
Adjusted 2D array of longitude values.
lat : numpy.ndarray
Adjusted 2D array of latitude values.
field : numpy.ma.MaskedArray
Adjusted 2D array of field data.
Example
-------
>>> lon, lat, field = adjust_pop_grid(tlon, tlat, field)
"""
nj = tlon.shape[0]
ni = tlon.shape[1]
xL = int(ni/2 - 1)
xR = int(xL + ni)
tlon = np.where(np.greater_equal(tlon,min(tlon[:,0])),tlon-360.,tlon)
lon = np.concatenate((tlon,tlon+360.),1)
lon = lon[:,xL:xR]
if ni == 320:
lon[367:-3,0] = lon[367:-3,0]+360.
lon = lon - 360.
lon = np.hstack((lon,lon[:,0:1]+360.))
if ni == 320:
lon[367:,-1] = lon[367:,-1] - 360.
# Trick cartopy into doing the right thing:
# it gets confused when the cyclic coords are identical
lon[:,0] = lon[:,0]-1e-8
# Periodicity
lat = np.concatenate((tlat,tlat),1)
lat = lat[:,xL:xR]
lat = np.hstack((lat,lat[:,0:1]))
field = np.ma.concatenate((field,field),1)
field = field[:,xL:xR]
field = np.ma.hstack((field,field[:,0:1]))
return lon,lat,field
Making the map
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(1,1,1, projection=ccrs.Robinson(central_longitude=305.0))
# Using the utilities we added above to process our data, and plotting it
lon, lat, field = adjust_pop_grid(lons, lats, ds["TEMP"].isel(time=0, z_t=0))
pc1=ax.pcolormesh(lon, lat,field, cmap='plasma',
vmin=0, vmax=30,
transform=ccrs.PlateCarree())
# Adding the land features
land = cartopy.feature.NaturalEarthFeature('physical', 'land', scale='110m', edgecolor='k', facecolor='white', linewidth=0.5)
ax.add_feature(land)
# Adding colorbar and title
cbar1 = fig.colorbar(pc1, ax=ax,extend='max',label=ds["TEMP"].units)
ax.set_title('CESM Surface Temperature', fontsize=10)
plt.show()
Let’s try the same thing with another variable, salinity (SALT
). We replace which variable we’re extracting from ds
in the adjust_pop_grid()
function, where we preprocess the data. If you’re trying this on your own, some other good ones to try looking at are dissolved inorganic carbon (DIC
), oxygen (O2
), or pH (PH
).
fig = plt.figure(figsize=(8,6))
ax = fig.add_subplot(1,1,1, projection=ccrs.Robinson(central_longitude=305.0))
# Using the utilities we added above to process our data, and plotting it
lon, lat, field = adjust_pop_grid(lons, lats, ds['SALT'].isel(time=0, z_t=0))
# Pick a different colorscheme from the plot above so we can distinguish them more easily
pc1=ax.pcolormesh(lon, lat,field, cmap='cividis',
vmin=32, vmax=38,
transform=ccrs.PlateCarree())
# Adding the land features
land = cartopy.feature.NaturalEarthFeature('physical', 'land', scale='110m', edgecolor='k', facecolor='white', linewidth=0.5)
ax.add_feature(land)
# Adding colorbar and title
cbar1 = fig.colorbar(pc1, ax=ax,extend='both',label=ds["SALT"].units)
ax.set_title('CESM Surface Salinity', fontsize=10)
plt.show()
Close the Dask cluster we spun up at the beginning.
cluster.close()
Summary
You’ve learned how to make simple plots of CESM output.