Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Make Diagnostic Plots for NA-CORDEX Zarr Stores

The NA-CORDEX data archive contains output from regional climate models (RCMs) run over a domain covering most of North America using boundary conditions from global climate model (GCM) simulations in the CMIP5 archive. It differs from many climate datasets by combining runs from many independently derived simulations. The usage of Zarr, Xarray, and Intake-ESM help simplify the problem of examining these disparate runs.

See the README file for more pointers and information on the NA-CORDEX data archive.

Overview

This cookbook provides useful methods for summarizing data values in large climate datasets. It clearly shows where data have extreme values and where data are missing; this can be useful for validating that the data were gathered and stored correctly. While this cookbook is specifically designed to examine any portion of the NA-CORDEX dataset using an intake catalog, the code can be adapted straightforwardly to other datasets that can be loaded via xarray.

Topics covered in this notebook include:

  1. Different Ways to Create and Connect to Dask Distributed Cluster

  2. How to Find and Obtain Data Using an Intake-ESM Catalog

  3. How to Create Various Statistical Summary Plots with matplotlib

Prerequisites

To more fully understand how the code in this notebook works, users are encouraged to explore the following introductory articles.

ConceptsImportanceNotes
Intro to XarrayHelpful
Dask Arrays with XarrayHelpful
Understanding of Zarr MetadataHelpfulFamiliarity with metadata structure
Understanding of MatplotlibHelpfulFamiliarity with plot elements in matplotlib
  • Time to learn: 45 minutes

Note: This notebook contains optional choices for running on NCAR supercomputers. These can be ignored for users running outside of the NCAR domain.


Imports

The main python packages used are xarray, intake-esm, dask, and matplotlib.

Because some of the CORDEX data have been interpolated from a Lambert Conformal grid onto a rectangular grid for ease of use, there can be many missing values on the edges of the interpolated grid. For this reason, we also turn off warnings complaining about missing values in the data.

env: PYTHONWARNINGS=ignore

Select User Options

Users may choose between:

  • Cloud storage provider (Amazon AWS or NCAR),

  • Whether to truncate the data if running on a resource-limited computer,

  • Whether to obtain a Dask cluster from a PBS Scheduler or via the Dask Gateway package.

Note: Using the NCAR cloud storage system requires a login account on an NCAR HPC computer.

Choose Cloud Storage (Amazon AWS or NCAR Cloud)

Choose whether to truncate data for resource-limited computers

When running this notebook where compute resources are limited, or data transfer rates are slow, set TRUNCATE_DATA to True. This will limit time ranges to 3 years from the start of a chosen NA-CORDEX scenario.

Choose whether to use a PBS Scheduler

If running on a HPC computer with a PBS Scheduler, set to True. Otherwise, set to False.

Choose whether to use Dask Gateway

If running on Jupyter server with Dask Gateway configured, set to True. Otherwise, set to False.

Create and Connect to Dask Distributed Cluster

Loading...

☝️ Link to Dask dashboard will appear above.

Find and Obtain Data Using an Intake Catalog

Define the Intake Catalog URL and Storage Access Options

Open catalog and produce a content summary

/tmp/ipykernel_4503/2356137384.py:2: DeprecationWarning: read_csv_kwargs is deprecated and will be removed in a future version. Please use read_kwargs instead.
  col = intake.open_esm_datastore(catalog_url, read_csv_kwargs={"converters": {"na-cordex-models": ast.literal_eval}},)
Loading...
Loading...
variable: ['hurs', 'huss', 'pr', 'prec', 'ps', 'rsds', 'sfcWind', 'tas', 'tasmax', 'tasmin', 'temp', 'tmax', 'tmin', 'uas', 'vas']

scenario: ['eval', 'hist-rcp45', 'hist-rcp85', 'hist', 'rcp45', 'rcp85']

grid: ['NAM-22i', 'NAM-44i']

na-cordex-models: ['ERA-Int.CRCM5-UQAM', 'ERA-Int.CRCM5-OUR', 'ERA-Int.RegCM4', 'ERA-Int.CanRCM4', 'ERA-Int.WRF', 'ERA-Int.HIRHAM5', 'ERA-Int.RCA4', 'CanESM2.CanRCM4', 'GFDL-ESM2M.CRCM5-OUR', 'CanESM2.CRCM5-OUR', 'MPI-ESM-LR.CRCM5-UQAM', 'CanESM2.CRCM5-UQAM', 'EC-EARTH.HIRHAM5', 'EC-EARTH.RCA4', 'CanESM2.RCA4', 'MPI-ESM-MR.CRCM5-UQAM', 'GEMatm-Can.CRCM5-UQAM', 'GEMatm-MPI.CRCM5-UQAM', 'HadGEM2-ES.RegCM4', 'GFDL-ESM2M.RegCM4', 'MPI-ESM-LR.RegCM4', 'HadGEM2-ES.WRF', 'GFDL-ESM2M.WRF', 'MPI-ESM-LR.WRF', 'CNRM-CM5.CRCM5-OUR', 'MPI-ESM-LR.CRCM5-OUR']

bias_correction: ['raw', 'mbcn-Daymet', 'mbcn-gridMET']

Load data into xarray using the catalog

Choose any combination of variable, grid, scenario, and bias correction listed in the catalog.

Below we choose the variable ‘tmax’ (Maximum Daily Surface Temperature) as a default for its ease of interpretation. For this example, we also choose a lower-resolution grid and the scenario with the shortest time range (15 years) to reduce the default data processing requirements.

Loading...
Loading...

--> The keys in the returned dictionary of datasets are constructed as follows:
	'variable.frequency.scenario.grid.bias_correction'
Loading...
Loading...

Dataset dictionary keys:
 dict_keys(['tmax.day.eval.NAM-44i.raw'])
Loading...

Functions for Subsetting and Plotting

Helper Function to Create a Single Map Plot

Helper Function for Finding Dates with Available Data

Helper Function for Truncating Data Slices

Function Producing Maps of First, Middle, and Final Timesteps

Function Producing Statistical Map Plots

Function Producing Time Series Plots

Also show which dates have no available data values, as a rug plot.

Produce Diagnostic Plots

Plot First, Middle, and Final Timesteps for Several Output Runs (less compute intensive)

<Figure size 1800x1200 with 12 Axes>
CPU times: user 7.36 s, sys: 1.88 s, total: 9.25 s
Wall time: 3min

Optional: Save figure to a PNG file

Change the value of SAVE_PLOT to True to produce a PNG file of the plot. The file will be saved in the same folder as this notebook.

Then use Jupyter’s file browser to locate the file and right-click the file to download it.

Create Statistical Map Plots for Several Output Runs (more compute intensive)

<Figure size 2500x1200 with 16 Axes>
CPU times: user 5.94 s, sys: 1.16 s, total: 7.1 s
Wall time: 1min 56s

Optional: Save figure to a PNG file

Change the value of SAVE_PLOT to True to produce a PNG file of the plot. The file will be saved in the same folder as this notebook.

Then use Jupyter’s file browser to locate the file and right-click the file to download it.

Plot Time Series for Several Output Runs (more compute intensive)

<Figure size 2500x2000 with 4 Axes>
CPU times: user 5.22 s, sys: 1.04 s, total: 6.26 s
Wall time: 1min 38s

Optional: Save figure to a PNG file

Change the value of SAVE_PLOT to True to produce a PNG file of the plot. The file will be saved in the same folder as this notebook.

Then use Jupyter’s file browser to locate the file and right-click the file to download it.

Release the workers.

Sun Oct 11 03:33:32 UTC 2026
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fbda8ea0cd0>
Unclosed connector
connections: ['deque([(<aiohttp.client_proto.ResponseHandler object at 0x7fbda8129a50>, 565.785889727), (<aiohttp.client_proto.ResponseHandler object at 0x7fbda3da0c50>, 566.788586753)])']
connector: <aiobotocore.httpsession._ProxySSLTCPConnector object at 0x7fbda8e52f50>
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7fb2381d6ad0>
Unclosed connector
connections: ['deque([(<aiohttp.client_proto.ResponseHandler object at 0x7fb2333dfa50>, 566.150231974), (<aiohttp.client_proto.ResponseHandler object at 0x7fb23328d5d0>, 567.037698655)])']
connector: <aiobotocore.httpsession._ProxySSLTCPConnector object at 0x7fb2381e7010>
Unclosed client session
client_session: <aiohttp.client.ClientSession object at 0x7f5cc87f6f90>
Unclosed connector
connections: ['deque([(<aiohttp.client_proto.ResponseHandler object at 0x7f5caa2e3cd0>, 565.784205274), (<aiohttp.client_proto.ResponseHandler object at 0x7f5caa2f20d0>, 566.997285396)])']
connector: <aiobotocore.httpsession._ProxySSLTCPConnector object at 0x7f5cc83c3610>

Show which python package versions were used

distributed: 2026.8.0
intake     : 2.0.9
matplotlib : 3.11.2
numpy      : 2.4.6
xarray     : 2026.9.0