Reproducing Key Figures from Kay et al. (2015)
Overview
This notebook demonstrates how one might use the NCAR Community Earth System Model (CESM) Large Ensemble (LENS) data hosted on AWS S3. The notebook shows how to reproduce figures 2 and 4 from the Kay et al. (2015) paper describing the CESM LENS dataset.
This resource is intended to be helpful for people not familiar with elements of the Pangeo framework including Jupyter Notebooks, Xarray, and Zarr data format, or with the original paper, so it includes additional explanation.
Prerequisites
Concepts |
Importance |
Notes |
---|---|---|
Necessary |
||
Dask |
Helpful |
Time to learn: 30 minutes
Imports
import sys
import os
import warnings
warnings.filterwarnings("ignore")
import intake
import matplotlib.pyplot as plt
from dask.distributed import Client
import numpy as np
import pandas as pd
import xarray as xr
import cmaps # for NCL colormaps
import cartopy.crs as ccrs
import dask
dask.config.set({"distributed.scheduler.worker-saturation": 1.0})
<dask.config.set at 0x7f46749317f0>
Create and Connect to Dask Distributed Cluster
Here we’ll use a dask cluster to parallelize our analysis.
platform = sys.platform
if (platform == 'win32'):
import multiprocessing.popen_spawn_win32
else:
import multiprocessing.popen_spawn_posix
client = Client()
client
Client
Client-7d45809a-f07e-11ee-89d1-000d3a383fbe
Connection method: Cluster object | Cluster type: distributed.LocalCluster |
Dashboard: http://127.0.0.1:8787/status |
Cluster Info
LocalCluster
993e86b1
Dashboard: http://127.0.0.1:8787/status | Workers: 4 |
Total threads: 4 | Total memory: 15.61 GiB |
Status: running | Using processes: True |
Scheduler Info
Scheduler
Scheduler-9351a1b0-63d6-40e3-a642-7874781a9802
Comm: tcp://127.0.0.1:33757 | Workers: 4 |
Dashboard: http://127.0.0.1:8787/status | Total threads: 4 |
Started: Just now | Total memory: 15.61 GiB |
Workers
Worker: 0
Comm: tcp://127.0.0.1:39775 | Total threads: 1 |
Dashboard: http://127.0.0.1:40663/status | Memory: 3.90 GiB |
Nanny: tcp://127.0.0.1:45957 | |
Local directory: /tmp/dask-scratch-space/worker-cnjr370d |
Worker: 1
Comm: tcp://127.0.0.1:38629 | Total threads: 1 |
Dashboard: http://127.0.0.1:43419/status | Memory: 3.90 GiB |
Nanny: tcp://127.0.0.1:39705 | |
Local directory: /tmp/dask-scratch-space/worker-_d55tmd7 |
Worker: 2
Comm: tcp://127.0.0.1:44949 | Total threads: 1 |
Dashboard: http://127.0.0.1:34633/status | Memory: 3.90 GiB |
Nanny: tcp://127.0.0.1:42395 | |
Local directory: /tmp/dask-scratch-space/worker-0kap2hmy |
Worker: 3
Comm: tcp://127.0.0.1:36057 | Total threads: 1 |
Dashboard: http://127.0.0.1:37243/status | Memory: 3.90 GiB |
Nanny: tcp://127.0.0.1:44017 | |
Local directory: /tmp/dask-scratch-space/worker-l414ld2s |
Load and Prepare Data
catalog_url = 'https://ncar-cesm-lens.s3-us-west-2.amazonaws.com/catalogs/aws-cesm1-le.json'
col = intake.open_esm_datastore(catalog_url)
col
aws-cesm1-le catalog with 56 dataset(s) from 442 asset(s):
unique | |
---|---|
variable | 78 |
long_name | 75 |
component | 5 |
experiment | 4 |
frequency | 6 |
vertical_levels | 3 |
spatial_domain | 5 |
units | 25 |
start_time | 12 |
end_time | 13 |
path | 427 |
derived_variable | 0 |
Show the first few lines of the catalog:
col.df.head(10)
variable | long_name | component | experiment | frequency | vertical_levels | spatial_domain | units | start_time | end_time | path | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | FLNS | net longwave flux at surface | atm | 20C | daily | 1.0 | global | W/m2 | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-FLNS.... |
1 | FLNSC | clearsky net longwave flux at surface | atm | 20C | daily | 1.0 | global | W/m2 | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-FLNSC... |
2 | FLUT | upwelling longwave flux at top of model | atm | 20C | daily | 1.0 | global | W/m2 | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-FLUT.... |
3 | FSNS | net solar flux at surface | atm | 20C | daily | 1.0 | global | W/m2 | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-FSNS.... |
4 | FSNSC | clearsky net solar flux at surface | atm | 20C | daily | 1.0 | global | W/m2 | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-FSNSC... |
5 | FSNTOA | net solar flux at top of atmosphere | atm | 20C | daily | 1.0 | global | W/m2 | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-FSNTO... |
6 | ICEFRAC | fraction of sfc area covered by sea-ice | atm | 20C | daily | 1.0 | global | fraction | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-ICEFR... |
7 | LHFLX | surface latent heat flux | atm | 20C | daily | 1.0 | global | W/m2 | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-LHFLX... |
8 | PRECL | large-scale (stable) precipitation rate (liq +... | atm | 20C | daily | 1.0 | global | m/s | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-PRECL... |
9 | PRECSC | convective snow rate (water equivalent) | atm | 20C | daily | 1.0 | global | m/s | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-PRECS... |
Show expanded version of collection structure with details:
col.keys_info().head()
component | experiment | frequency | |
---|---|---|---|
key | |||
atm.20C.daily | atm | 20C | daily |
atm.20C.hourly6-1990-2005 | atm | 20C | hourly6-1990-2005 |
atm.20C.monthly | atm | 20C | monthly |
atm.20C.static | atm | 20C | static |
atm.CTRL.daily | atm | CTRL | daily |
Extract data needed to construct Figure 2
Search the catalog to find the desired data, in this case the reference height temperature of the atmosphere, at daily time resolution, for the Historical, 20th Century, and RCP8.5 (IPCC Representative Concentration Pathway 8.5) experiments.
col_subset = col.search(frequency=["daily", "monthly"], component="atm", variable="TREFHT",
experiment=["20C", "RCP85", "HIST"])
col_subset
aws-cesm1-le catalog with 6 dataset(s) from 6 asset(s):
unique | |
---|---|
variable | 1 |
long_name | 1 |
component | 1 |
experiment | 3 |
frequency | 2 |
vertical_levels | 1 |
spatial_domain | 1 |
units | 1 |
start_time | 6 |
end_time | 6 |
path | 6 |
derived_variable | 0 |
col_subset.df
variable | long_name | component | experiment | frequency | vertical_levels | spatial_domain | units | start_time | end_time | path | |
---|---|---|---|---|---|---|---|---|---|---|---|
0 | TREFHT | reference height temperature | atm | 20C | daily | 1.0 | global | K | 1920-01-01 12:00:00 | 2005-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-20C-TREFH... |
1 | TREFHT | reference height temperature | atm | HIST | daily | 1.0 | global | K | 1850-01-01 12:00:00 | 1919-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-HIST-TREF... |
2 | TREFHT | reference height temperature | atm | RCP85 | daily | 1.0 | global | K | 2006-01-01 12:00:00 | 2100-12-31 12:00:00 | s3://ncar-cesm-lens/atm/daily/cesmLE-RCP85-TRE... |
3 | TREFHT | reference height temperature | atm | 20C | monthly | 1.0 | global | K | 1920-01-16 12:00:00 | 2005-12-16 12:00:00 | s3://ncar-cesm-lens/atm/monthly/cesmLE-20C-TRE... |
4 | TREFHT | reference height temperature | atm | HIST | monthly | 1.0 | global | K | 1850-01-16 12:00:00 | 1919-12-16 12:00:00 | s3://ncar-cesm-lens/atm/monthly/cesmLE-HIST-TR... |
5 | TREFHT | reference height temperature | atm | RCP85 | monthly | 1.0 | global | K | 2006-01-16 12:00:00 | 2100-12-16 12:00:00 | s3://ncar-cesm-lens/atm/monthly/cesmLE-RCP85-T... |
Load catalog entries for subset into a dictionary of Xarray Datasets:
dsets = col_subset.to_dataset_dict(zarr_kwargs={"consolidated": True}, storage_options={"anon": True})
print(f"\nDataset dictionary keys:\n {dsets.keys()}")
--> The keys in the returned dictionary of datasets are constructed as follows:
'component.experiment.frequency'
Dataset dictionary keys:
dict_keys(['atm.HIST.monthly', 'atm.20C.monthly', 'atm.20C.daily', 'atm.RCP85.daily', 'atm.RCP85.monthly', 'atm.HIST.daily'])
Define Xarray Datasets corresponding to the three experiments:
ds_HIST = dsets['atm.HIST.monthly']
ds_20C = dsets['atm.20C.daily']
ds_RCP85 = dsets['atm.RCP85.daily']
Use the dask.distributed
utility function to display size of each dataset:
from dask.utils import format_bytes
print(f"Historical: {format_bytes(ds_HIST.nbytes)}\n"
f"20th Century: {format_bytes(ds_20C.nbytes)}\n"
f"RCP8.5: {format_bytes(ds_RCP85.nbytes)}")
Historical: 177.21 MiB
20th Century: 258.65 GiB
RCP8.5: 285.71 GiB
Now, extract the Reference Height Temperature data variable:
t_hist = ds_HIST["TREFHT"]
t_20c = ds_20C["TREFHT"]
t_rcp = ds_RCP85["TREFHT"]
t_20c
<xarray.DataArray 'TREFHT' (member_id: 40, time: 31390, lat: 192, lon: 288)> Size: 278GB dask.array<open_dataset-TREFHT, shape=(40, 31390, 192, 288), dtype=float32, chunksize=(1, 576, 192, 288), chunktype=numpy.ndarray> Coordinates: * lat (lat) float64 2kB -90.0 -89.06 -88.12 -87.17 ... 88.12 89.06 90.0 * lon (lon) float64 2kB 0.0 1.25 2.5 3.75 ... 355.0 356.2 357.5 358.8 * member_id (member_id) int64 320B 1 2 3 4 5 6 7 ... 35 101 102 103 104 105 * time (time) object 251kB 1920-01-01 12:00:00 ... 2005-12-31 12:00:00 Attributes: cell_methods: time: mean long_name: Reference height temperature units: K
The global surface temperature anomaly was computed relative to the 1961-90 base period in the Kay et al. paper, so extract that time slice:
t_ref = t_20c.sel(time=slice("1961", "1990"))
Figure 2
Read grid cell areas
Cell size varies with latitude, so this must be accounted for when computing the global mean.
cat = col.search(frequency="static", component="atm", experiment=["20C"])
_, grid = cat.to_dataset_dict(aggregate=False, storage_options={'anon':True}, zarr_kwargs={"consolidated": True}).popitem()
grid
--> The keys in the returned dictionary of datasets are constructed as follows:
'variable.long_name.component.experiment.frequency.vertical_levels.spatial_domain.units.start_time.end_time.path'
<xarray.Dataset> Size: 242kB Dimensions: (lat: 192, lon: 288, ilev: 31, lev: 30, bnds: 2, slat: 191, slon: 288) Coordinates: (12/20) P0 float64 8B ... area (lat, lon) float32 221kB dask.array<chunksize=(192, 288), meta=np.ndarray> gw (lat) float64 2kB dask.array<chunksize=(192,), meta=np.ndarray> hyai (ilev) float64 248B dask.array<chunksize=(31,), meta=np.ndarray> hyam (lev) float64 240B dask.array<chunksize=(30,), meta=np.ndarray> hybi (ilev) float64 248B dask.array<chunksize=(31,), meta=np.ndarray> ... ... ntrm int32 4B ... ntrn int32 4B ... * slat (slat) float64 2kB -89.53 -88.59 -87.64 ... 87.64 88.59 89.53 * slon (slon) float64 2kB -0.625 0.625 1.875 3.125 ... 355.6 356.9 358.1 w_stag (slat) float64 2kB dask.array<chunksize=(191,), meta=np.ndarray> wnummax (lat) int32 768B dask.array<chunksize=(192,), meta=np.ndarray> Dimensions without coordinates: bnds Data variables: *empty* Attributes: intake_esm_vars: nan intake_esm_attrs:component: atm intake_esm_attrs:experiment: 20C intake_esm_attrs:frequency: static intake_esm_attrs:spatial_domain: global intake_esm_attrs:path: s3://ncar-cesm-lens/atm/static/grid.zarr intake_esm_attrs:_data_format_: zarr intake_esm_dataset_key: atm.20C.static.global.s3://ncar-cesm-le...
cell_area = grid.area.load()
total_area = cell_area.sum()
cell_area
<xarray.DataArray 'area' (lat: 192, lon: 288)> Size: 221kB array([[2.994837e+07, 2.994837e+07, 2.994837e+07, ..., 2.994837e+07, 2.994837e+07, 2.994837e+07], [2.395748e+08, 2.395748e+08, 2.395748e+08, ..., 2.395748e+08, 2.395748e+08, 2.395748e+08], [4.790848e+08, 4.790848e+08, 4.790848e+08, ..., 4.790848e+08, 4.790848e+08, 4.790848e+08], ..., [4.790848e+08, 4.790848e+08, 4.790848e+08, ..., 4.790848e+08, 4.790848e+08, 4.790848e+08], [2.395748e+08, 2.395748e+08, 2.395748e+08, ..., 2.395748e+08, 2.395748e+08, 2.395748e+08], [2.994837e+07, 2.994837e+07, 2.994837e+07, ..., 2.994837e+07, 2.994837e+07, 2.994837e+07]], dtype=float32) Coordinates: P0 float64 8B 1e+05 area (lat, lon) float32 221kB 2.995e+07 2.995e+07 ... 2.995e+07 gw (lat) float64 2kB 3.382e-05 nan nan nan ... nan nan nan 3.382e-05 * lat (lat) float64 2kB -90.0 -89.06 -88.12 -87.17 ... 88.12 89.06 90.0 * lon (lon) float64 2kB 0.0 1.25 2.5 3.75 5.0 ... 355.0 356.2 357.5 358.8 ntrk int32 4B 1 ntrm int32 4B 1 ntrn int32 4B 1 wnummax (lat) int32 768B 1 -2147483648 -2147483648 ... -2147483648 1 Attributes: long_name: Grid-Cell Area standard_name: cell_area units: m2
Define weighted means
Note: resample(time="AS")
does an annual resampling based on start of calendar year. See documentation for Pandas resampling options.
t_ref_ts = (
(t_ref.resample(time="AS").mean("time") * cell_area).sum(dim=("lat", "lon"))
/ total_area
).mean(dim=("time", "member_id"))
t_hist_ts = (
(t_hist.resample(time="AS").mean("time") * cell_area).sum(dim=("lat", "lon"))
) / total_area
t_20c_ts = (
(t_20c.resample(time="AS").mean("time") * cell_area).sum(dim=("lat", "lon"))
) / total_area
t_rcp_ts = (
(t_rcp.resample(time="AS").mean("time") * cell_area).sum(dim=("lat", "lon"))
) / total_area
Read data and compute means
Dask’s “lazy execution” philosophy means that until this point we have not actually read the bulk of the data. Steps 1, 3, and 4 take a while to complete, so we include the Notebook “cell magic” directive %%time
to display elapsed and CPU times after computation.
Step 1 (takes a while)
%%time
# this cell takes a while, be patient
t_ref_mean = t_ref_ts.load()
t_ref_mean
CPU times: user 40.6 s, sys: 8.3 s, total: 48.9 s
Wall time: 14min 1s
<xarray.DataArray ()> Size: 4B array(286.38763, dtype=float32) Coordinates: P0 float64 8B 1e+05 ntrk int32 4B 1 ntrm int32 4B 1 ntrn int32 4B 1
Step 2 (executes quickly)
%%time
t_hist_ts_df = t_hist_ts.to_series().T
#t_hist_ts_df.head()
CPU times: user 595 ms, sys: 58.1 ms, total: 653 ms
Wall time: 7.04 s
Step 3 (takes even longer than Step 1)
%%time
t_20c_ts_df = t_20c_ts.to_series().unstack().T
t_20c_ts_df.head()
CPU times: user 1min 57s, sys: 20.7 s, total: 2min 18s
Wall time: 49min 13s
member_id | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ... | 31 | 32 | 33 | 34 | 35 | 101 | 102 | 103 | 104 | 105 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
time | |||||||||||||||||||||
1920-01-01 00:00:00 | 286.311310 | 286.346710 | 286.283875 | 286.363983 | 286.328400 | 286.373444 | 286.386017 | 286.302185 | 286.374878 | 286.348358 | ... | 286.243469 | 286.283783 | 286.173859 | 286.309509 | 286.296234 | 286.341064 | 286.341187 | 286.376831 | 286.321167 | 286.254822 |
1921-01-01 00:00:00 | 286.250641 | 286.198181 | 286.287292 | 286.390564 | 286.309204 | 286.334229 | 286.311310 | 286.300232 | 286.315857 | 286.305603 | ... | 286.179413 | 286.315643 | 286.075104 | 286.295990 | 286.318085 | 286.375305 | 286.246063 | 286.356201 | 286.492493 | 286.224274 |
1922-01-01 00:00:00 | 286.293488 | 286.296356 | 286.265686 | 286.336517 | 286.293579 | 286.220093 | 286.010773 | 286.195099 | 286.205170 | 286.396545 | ... | 286.142365 | 286.316254 | 286.140167 | 286.293549 | 286.327972 | 286.142365 | 286.412598 | 286.369232 | 286.503418 | 286.282074 |
1923-01-01 00:00:00 | 286.329163 | 286.322662 | 286.251099 | 286.322723 | 286.237457 | 286.152069 | 286.066010 | 286.204498 | 286.271423 | 286.292236 | ... | 286.168762 | 286.300781 | 286.095490 | 286.116302 | 286.227905 | 286.226471 | 286.512909 | 286.381348 | 286.215302 | 286.396332 |
1924-01-01 00:00:00 | 286.307465 | 286.237366 | 286.148895 | 286.311890 | 286.361694 | 286.185974 | 286.248322 | 286.288177 | 286.330444 | 286.411835 | ... | 286.143066 | 286.287079 | 286.234100 | 286.199890 | 286.252777 | 286.322815 | 286.256195 | 286.221588 | 286.247437 | 286.422028 |
5 rows × 40 columns
Step 4 (similar to Step 3 in its execution time)
%%time
# This also takes a while
t_rcp_ts_df = t_rcp_ts.to_series().unstack().T
t_rcp_ts_df.head()
CPU times: user 1min 52s, sys: 20.7 s, total: 2min 13s
Wall time: 46min 6s
member_id | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | ... | 31 | 32 | 33 | 34 | 35 | 101 | 102 | 103 | 104 | 105 |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
time | |||||||||||||||||||||
2006-01-01 00:00:00 | 286.764832 | 286.960358 | 286.679230 | 286.793152 | 286.754547 | 287.022339 | 286.850464 | 287.089844 | 286.960022 | 286.775787 | ... | 286.866089 | 286.925049 | 286.663971 | 286.955414 | 286.712524 | 287.115601 | 286.863556 | 286.881683 | 287.308411 | 287.030334 |
2007-01-01 00:00:00 | 287.073792 | 286.908539 | 286.808746 | 286.998901 | 286.841675 | 286.993042 | 286.914124 | 286.938965 | 286.933563 | 286.675385 | ... | 286.804108 | 286.849548 | 286.628204 | 287.010529 | 286.811554 | 287.187225 | 286.862823 | 287.008270 | 287.222534 | 287.239044 |
2008-01-01 00:00:00 | 287.104095 | 286.815033 | 286.995056 | 287.081543 | 287.100708 | 286.960510 | 286.854706 | 286.878937 | 287.062927 | 286.702454 | ... | 286.825653 | 286.844086 | 286.811859 | 286.803741 | 286.956635 | 287.080994 | 286.930084 | 286.945801 | 287.087128 | 287.157745 |
2009-01-01 00:00:00 | 286.984497 | 287.059448 | 287.010498 | 287.144714 | 286.948700 | 287.092316 | 286.888458 | 287.050934 | 287.138428 | 286.890839 | ... | 286.785797 | 286.876556 | 286.953094 | 287.060364 | 287.056946 | 287.124908 | 287.005615 | 287.083984 | 287.254211 | 287.060730 |
2010-01-01 00:00:00 | 286.991821 | 287.102295 | 286.988129 | 286.875183 | 286.954407 | 287.121796 | 286.938843 | 287.116211 | 286.957245 | 287.049622 | ... | 286.937317 | 286.928314 | 286.980499 | 287.118713 | 287.178040 | 287.030212 | 287.114716 | 287.083038 | 287.256927 | 287.066528 |
5 rows × 40 columns
Get observations for Figure 2 (HadCRUT4; Morice et al. 2012)
Observational time series data for comparison with ensemble average:
obsDataURL = "https://www.esrl.noaa.gov/psd/thredds/dodsC/Datasets/cru/hadcrut4/air.mon.anom.median.nc"
ds = xr.open_dataset(obsDataURL).load()
ds
<xarray.Dataset> Size: 21MB Dimensions: (lat: 36, lon: 72, time: 2063, nbnds: 2) Coordinates: * lat (lat) float32 144B 87.5 82.5 77.5 72.5 ... -77.5 -82.5 -87.5 * lon (lon) float32 288B -177.5 -172.5 -167.5 ... 167.5 172.5 177.5 * time (time) datetime64[ns] 17kB 1850-01-01 1850-02-01 ... 2021-11-01 Dimensions without coordinates: nbnds Data variables: time_bnds (time, nbnds) datetime64[ns] 33kB 1850-01-01 ... 2021-11-30 air (time, lat, lon) float32 21MB nan nan nan nan ... nan nan nan nan Attributes: platform: Surface title: HADCRUT4 Combined Air Temperature/SST An... history: Originally created at NOAA/ESRL PSD by C... Conventions: CF-1.0 Comment: This dataset supersedes V3 Source: Obtained from http://hadobs.metoffice.co... version: 4.2.0 _NCProperties: version=2,netcdf=4.6.3,hdf5=1.10.5 References: https://www.psl.noaa.gov/data/gridded/da... dataset_title: HadCRUT4 DODS_EXTRA.Unlimited_Dimension: time
def weighted_temporal_mean(ds):
"""
weight by days in each month
"""
time_bound_diff = ds.time_bnds.diff(dim="nbnds")[:, 0]
wgts = time_bound_diff.groupby("time.year") / time_bound_diff.groupby(
"time.year"
).sum(xr.ALL_DIMS)
obs = ds["air"]
cond = obs.isnull()
ones = xr.where(cond, 0.0, 1.0)
obs_sum = (obs * wgts).resample(time="AS").sum(dim="time")
ones_out = (ones * wgts).resample(time="AS").sum(dim="time")
obs_s = (obs_sum / ones_out).mean(("lat", "lon")).to_series()
return obs_s
Limit observations to 20th century:
obs_s = weighted_temporal_mean(ds)
obs_s = obs_s['1920':]
obs_s.head()
time
1920-01-01 -0.262006
1921-01-01 -0.195891
1922-01-01 -0.301986
1923-01-01 -0.269062
1924-01-01 -0.292857
Freq: YS-JAN, dtype: float64
all_ts_anom = pd.concat([t_20c_ts_df, t_rcp_ts_df]) - t_ref_mean.data
years = [val.year for val in all_ts_anom.index]
obs_years = [val.year for val in obs_s.index]
Combine ensemble member 1 data from historical and 20th century experiments:
hist_anom = t_hist_ts_df - t_ref_mean.data
member1 = pd.concat([hist_anom.iloc[:-2], all_ts_anom.iloc[:,0]], verify_integrity=True)
member1_years = [val.year for val in member1.index]
Plotting Figure 2
Global surface temperature anomaly (1961-90 base period) for individual ensemble members, and observations:
ax = plt.axes()
ax.tick_params(right=True, top=True, direction="out", length=6, width=2, grid_alpha=0.5)
ax.plot(years, all_ts_anom.iloc[:,1:], color="grey")
ax.plot(obs_years, obs_s['1920':], color="red")
ax.plot(member1_years, member1, color="black")
ax.text(
0.35,
0.4,
"observations",
verticalalignment="bottom",
horizontalalignment="left",
transform=ax.transAxes,
color="red",
fontsize=10,
)
ax.text(
0.35,
0.33,
"members 2-40",
verticalalignment="bottom",
horizontalalignment="left",
transform=ax.transAxes,
color="grey",
fontsize=10,
)
ax.text(
0.05,
0.2,
"member 1",
verticalalignment="bottom",
horizontalalignment="left",
transform=ax.transAxes,
color="black",
fontsize=10,
)
ax.set_xticks([1850, 1920, 1950, 2000, 2050, 2100])
plt.ylim(-1, 5)
plt.xlim(1850, 2100)
plt.ylabel("Global Surface\nTemperature Anomaly (K)")
plt.show()
Figure 4
Compute linear trend for winter seasons
def linear_trend(da, dim="time"):
da_chunk = da.chunk({dim: -1})
trend = xr.apply_ufunc(
calc_slope,
da_chunk,
vectorize=True,
input_core_dims=[[dim]],
output_core_dims=[[]],
output_dtypes=[np.float64],
dask="parallelized",
)
return trend
def calc_slope(y):
"""ufunc to be used by linear_trend"""
x = np.arange(len(y))
# drop missing values (NaNs) from x and y
finite_indexes = ~np.isnan(y)
slope = np.nan if (np.sum(finite_indexes) < 2) else np.polyfit(x[finite_indexes], y[finite_indexes], 1)[0]
return slope
Compute ensemble trends
%%time
# Takes several minutes
t = xr.concat([t_20c, t_rcp], dim="time")
seasons = t.sel(time=slice("1979", "2012")).resample(time="QS-DEC").mean("time")
# Include only full seasons from 1979 and 2012
seasons = seasons.sel(time=slice("1979", "2012")).load()
CPU times: user 46.7 s, sys: 9.64 s, total: 56.4 s
Wall time: 16min 28s
winter_seasons = seasons.sel(
time=seasons.time.where(seasons.time.dt.month == 12, drop=True)
)
winter_trends = linear_trend(
winter_seasons.chunk({"lat": 20, "lon": 20, "time": -1})
).load() * len(winter_seasons.time)
# Compute ensemble mean from the first 30 members
winter_trends_mean = winter_trends.isel(member_id=range(30)).mean(dim='member_id')
Make sure that we have 34 seasons:
assert len(winter_seasons.time) == 34
Get observations for Figure 4 (NASA GISS GisTemp)
This is observational time series data for comparison with ensemble average (NASA GISS Surface Temperature Analysis, https://data.giss.nasa.gov/gistemp/).
obsDataURL = "https://data.giss.nasa.gov/pub/gistemp/gistemp1200_GHCNv4_ERSSTv5.nc.gz"
Download, unzip, and load file:
os.system("wget " + obsDataURL)
obsDataFileName = obsDataURL.split('/')[-1]
os.system("gunzip " + obsDataFileName)
obsDataFileName = obsDataFileName[:-3]
ds = xr.open_dataset(obsDataFileName).load()
ds
--2024-04-02 01:28:26-- https://data.giss.nasa.gov/pub/gistemp/gistemp1200_GHCNv4_ERSSTv5.nc.gz
Resolving data.giss.nasa.gov (data.giss.nasa.gov)... 129.164.128.233, 2001:4d0:2310:230::233
Connecting to data.giss.nasa.gov (data.giss.nasa.gov)|129.164.128.233|:443... connected.
HTTP request sent, awaiting response... 200 OK
Length: 25398620 (24M) [application/x-gzip]
Saving to: ‘gistemp1200_GHCNv4_ERSSTv5.nc.gz’
0K .......... .......... .......... ..
........ .......... 0% 353K 70s
50K .......... .......... .......... .......... .......... 0% 713K 52s
100K .......... .......... .......... .......... .......... 0% 48.6M 35s
150K .......... .......... .......... .......... .......... 0% 43.7M 26s
200K .......... .......... .......... .......... .......... 1% 725K 28s
250K .......... .......... .......... .......... .......... 1% 45.8M 23s
300K .......... .......... .......... .......... .......... 1% 114M 20s
350K .......... .......... .......... .......... .......... 1% 75.7M 17s
400K .......... ......
.... .......... .......... .......... 1% 732K 19s
450K .......... .......... .......... .......... .......... 2% 95.9M 17s
500K .......... .......... .......... .......... .......... 2% 141M 16s
550K .......... .......... .......... .......... .......... 2% 99.5M 14s
600K .......... .......... .......... .......... .......... 2% 89.2M 13s
650K .......... .......... .......... .......... .......... 2% 118M 12s
700K .......... .......... .......... .......... .......... 3% 116M 11s
750K .......... .......... .......... .......... .......... 3% 139M 11s
800K .......... .......... .......... .......... .......... 3% 549K 13s
850K .......... .......... .......... .......... .......... 3% 176M 12s
900K .......... .......... .......... .......... .......... 3% 188M 11s
950K .......... .......... .......... .......... .......... 4% 248M 11s
1000K .......... .......... .......... .......... .......... 4% 213M 10s
1050K .......... .......... .......... .......... .......... 4% 253M 10s
1100K .......... .......... .......... .......... .......... 4% 233M 9s
1150K .......... .......... .......... .......... .......... 4% 152M 9s
1200K .......... .......... .......... .......... .......... 5% 205M 8s
1250K .......... .......... .......... .......... .......... 5% 726K 9s
1300K .......... .......... .......... .......... .......... 5% 70.5M 9s
1350K .......... .......... .......... .......... .......... 5% 180M 9s
1400K .......... .......... .......... .......... .......... 5% 161M 8s
1450K .......... .......... .......... .......... .......... 6% 28.2M 8s
1500K .......... .......... .......... .......... .......... 6% 141M 8s
1550K .......... ........
.. .......... .......... .......... 6% 1.11M 8s
1600K .......... .......... .......... .......... .......... 6% 30.4M 8s
1650K .......... .......... .......... .......... .......... 6% 106M 8s
1700K .......... .......... .......... .......... .......... 7% 135M 7s
1750K .......... .......... .......... .......... .......... 7% 162M 7s
1800K .......... .......... .......... .......... .......... 7% 218M 7s
1850K .......... .......... .......... .......... .......... 7% 250M 7s
1900K .......... .......... .......... .......... .......... 7% 270M 7s
1950K .......... .......... .......... .......... .......... 8% 273M 6s
2000K .......... .......... .......... .......... .......... 8% 197M 6s
2050K .......... .......... .......... .......... .......... 8% 231M 6s
2100K .......... .......... .......... .......... .......... 8% 222M 6s
2150K .......... .......... .......... .......... .......... 8% 218M 6s
2200K .......... .......... .......... .......... .......... 9% 273M 6s
2250K .......... .......... .......... .......... .......... 9% 248M 6s
2300K .......... .......... .......... .......... .......... 9% 229M 5s
2350K .......... .......... .......... .......... .......... 9% 225M 5s
2400K .......... .......... .......... .......... .......... 9% 51.3M 5s
2450K .......... .......... .......... .......... .......... 10% 2.83M 5s
2500K .......... .......... .......... .......... .......... 10% 47.5M 5s
2550K .......... .......... .......... .......... .......... 10% 22.3M 5s
2600K .......... .......... .......... .......... .......... 10% 1.11M 5s
2650K .......... .......... .......... .......... .......... 10% 19.5M 5s
2700K .......... .......... .......... .......... .......... 11% 543K 6s
2750K .......... .......... .......... .......... .......... 11% 131M 6s
2800K .......... .......... .......... .......... .......... 11% 108M 6s
2850K .......... .......... .......... .......... .......... 11% 154M 6s
2900K .......... .......... .......... .......... .......... 11% 22.4M 5s
2950K .......... .......... .......... .......... .......... 12% 160M 5s
3000K ........
.. .......... .......... .......... .......... 12% 1.10M 6s
3050K .......... .......... .......... .......... .......... 12% 167M 5s
3100K .......... .......... .......... .......... .......... 12% 183M 5s
3150K .......... .......... .......... .......... .......... 12% 192M 5s
3200K .......... .......... .......... .......... .......... 13% 211M 5s
3250K .......... .......... .......... .......... .......... 13% 237M 5s
3300K .......... .......... .......... .......... .......... 13% 216M 5s
3350K .......... .......... .......... .......... .......... 13% 203M 5s
3400K .......... .......... .......... .......... .......... 13% 212M 5s
3450K .......... .......... .......... .......... .......... 14% 258M 5s
3500K .......... .......... .......... .......... .......... 14% 253M 5s
3550K .......... .......... .......... .......... .......... 14% 106M 5s
3600K .......... .......... .......... .......... .......... 14% 24.7M 5s
3650K .......... .......... .......... .......... .......... 14% 104M 4s
3700K .......... .......... .......... .......... .......... 15% 94.0M 4s
3750K .......... .......... .......... .......... .......... 15% 2.84M 4s
3800K .......... .......... .......... .......... .......... 15% 16.9M 4s
3850K .......... .......... .......... .......... .......... 15% 1.08M 5s
3900K .......... .......... .......... .......... .......... 15% 36.2M 4s
3950K .......... .......... .......... .......... .......... 16% 58.3M 4s
4000K .......... .......... .......... .......... .......... 16% 24.3M 4s
4050K .......... .......... .......... .......... .......... 16% 83.7M 4s
4100K .......... .......... .......... .......... .......... 16% 60.1M 4s
4150K .......... .......... .......... .......... .......... 16% 2.98M 4s
4200K .......... .......... .......... .......... .......... 17% 25.7M 4s
4250K .......... .......... .......... .......... .......... 17% 2.61M 4s
4300K .......... .......... .......... .......... .......... 17% 1.71M 4s
4350K .......... .......... .......... .......... .......... 17% 35.1M 4s
4400K .......... .......... .......... .......... .......... 17% 25.0M 4s
4450K .......... .......... .......... .......... .......... 18% 66.4M 4s
4500K .......... .......... .......... .......... .......... 18% 48.4M 4s
4550K .......... .......... .......... .......... .......... 18% 3.03M 4s
4600K .......... .......... .......... .......... .......... 18% 23.7M 4s
4650K .......... .......... .......... .......... .......... 18% 19.5M 4s
4700K .......... ..........
.......... .......... .......... 19% 1.09M 4s
4750K .......... .......... .......... .......... .......... 19% 25.5M 4s
4800K .......... .......... .......... .......... .......... 19% 23.7M 4s
4850K .......... .......... .......... .......... .......... 19% 114M 4s
4900K .......... .......... .......... .......... .......... 19% 554K 4s
4950K .......... .......... .......... .......... .......... 20% 222M 4s
5000K .......... .......... .......... .......... .......... 20% 219M 4s
5050K .......... .......... .......... .......... .......... 20% 247M 4s
5100K .......... .......... .......... .......... .......... 20% 266M 4s
5150K .......... .......... .......... .......... .......... 20% 224M 4s
5200K .......... .......... .......... .......... .......... 21% 207M 4s
5250K .......... .......... .......... .......... .......... 21% 255M 4s
5300K .......... .......... .......... .......... .......... 21% 254M 4s
5350K .......... .......... .......... .......... .......... 21% 245M 4s
5400K .......... .......... .......... .......... .......... 21% 35.8M 4s
5450K .......... .......... .......... .......... .......... 22% 1.09M 4s
5500K .......... .......... .......... .......... .......... 22% 16.1M 4s
5550K .......... .......... .......... .......... .......... 22% 38.6M 4s
5600K .......... .......... .......... .......... .......... 22% 33.8M 4s
5650K .......... .......... .......... .......... .......... 22% 2.89M 4s
5700K .......... .......... .......... .......... .......... 23% 2.60M 4s
5750K ..........
.......... .......... .......... .......... 23% 1.67M 4s
5800K .......... .......... .......... .......... .......... 23% 16.0M 4s
5850K .......... .......... .......... .......... .......... 23% 42.2M 4s
5900K .......... .......... .......... .......... .......... 23% 31.6M 4s
5950K .......... .......... .......... .......... .......... 24% 3.03M 4s
6000K .......... .......... .......... .......... .......... 24% 1011K 4s
6050K .......... .......... .......... .......... .......... 24% 96.8M 4s
6100K .......... .......... .......... .......... .......... 24% 27.3M 4s
6150K .......... .......... .......... .......... .......... 24% 32.1M 4s
6200K .......... .......... .......... .......... .......... 25% 37.1M 4s
6250K .......... .......... .......... .......... .......... 25% 2.95M 4s
6300K .......... .......... .......... .......... .......... 25% 6.13M 4s
6350K .......... .......... .......... .......... .......... 25% 1.18M 4s
6400K .......... .......... .......... .......... .......... 26% 23.6M 4s
6450K .......... .......... ..........
.......... .......... 26% 553K 4s
6500K .......... .......... .......... .......... .......... 26% 15.5M 4s
6550K .......... .......... .......... .......... .......... 26% 215M 4s
6600K .......... .......... .......... .......... .......... 26% 228M 4s
6650K .......... .......... .......... .......... .......... 27% 259M 4s
6700K .......... .......... .......... .......... .......... 27% 233M 4s
6750K .......... .......... .......... .......... .......... 27% 230M 4s
6800K .......... .......... .......... .......... .......... 27% 185M 4s
6850K .......... .......... .......... .......... .......... 27% 3.37M 4s
6900K .......... .......... .......... .......... .......... 28% 1.36M 4s
6950K .......... .......... .......... .......... .......... 28% 44.2M 4s
7000K .......... .......... .......... .......... .......... 28% 18.3M 4s
7050K .......... .......... .......... .......... .......... 28% 3.25M 4s
7100K .......... .......... .......... .......... .......... 28% 964K 4s
7150K .......... .......... .......... .......... .......... 29% 53.5M 4s
7200K .......... .......... .......... .......... .......... 29% 44.0M 4s
7250K .......... .......... .......... .......... .......... 29% 3.33M 4s
7300K .......... .......... .......... .......... .......... 29% 928K 4s
7350K .......... .......... .......... .......... .......... 29% 51.9M 4s
7400K .......... .......... .......... .......... .......... 30% 45.9M 4s
7450K .......... .......... ..
........ .......... .......... 30% 3.85M 4s
7500K .......... .......... .......... .......... .......... 30% 4.13M 4s
7550K .......... .......... .......... .......... .......... 30% 1.10M 4s
7600K .......... .......... .......... .......... .......... 30% 34.4M 4s
7650K .......... .......... .......... .......... .......... 31% 3.91M 4s
7700K .......... .......... .......... .......... .......... 31% 11.7M 4s
7750K .......... .......... .......... .......... .......... 31% 956K 4s
7800K .......... .......... .......... .......... .......... 31% 48.9M 4s
7850K .......... .......... .......... .......... .......... 31% 35.6M 4s
7900K .......... .......... .......... .......... .......... 32% 3.88M 4s
7950K .......... .......... .......... .......... .......... 32% 2.54M 4s
8000K .......... .......... .......... .......... .......... 32% 1.32M 4s
8050K .......... .......... .......... .......... .......... 32% 42.7M 4s
8100K .......... .......... .......... .......... .......... 32% 3.98M 4s
8150K .......... .......... .......... .......... .......... 33% 11.6M 4s
8200K .......... .......... .......... .......... .......... 33% 951K 4s
8250K .......... .......... .......... .......... .......... 33% 67.2M 4s
8300K .......... .......... .......... .......... .......... 33% 10.1M 4s
8350K .......... .......... .......... .......... .......... 33% 5.45M 4s
8400K .......... .......... .......... .......... .......... 34% 905K 4s
8450K .......... .......... .......... .......... .......... 34% 38.9M 4s
8500K .......... .......... .......... .......... .......... 34% 35.7M 4s
8550K .......... .......... .......... .......... .......... 34% 4.19M 4s
8600K .......... .......... .......... .......... .......... 34% 10.8M 4s
8650K .......... .......... ..
........ .......... .......... 35% 948K 4s
8700K .......... .......... .......... .......... .......... 35% 561K 4s
8750K .......... .......... .......... .......... .......... 35% 224M 4s
8800K .......... .......... .......... .......... .......... 35% 5.94M 4s
8850K .......... .......... .......... .......... .......... 35% 270M 4s
8900K .......... .......... .......... .......... .......... 36% 257M 4s
8950K .......... .......... .......... .......... .......... 36% 275M 4s
9000K .......... .......... .......... .......... .......... 36% 236M 4s
9050K .......... .......... .......... .......... .......... 36% 7.62M 4s
9100K .......... .......... .......... .......... .......... 36% 1.22M 4s
9150K .......... .......... .......... .......... .......... 37% 5.72M 4s
9200K .......... .......... .......... .......... .......... 37% 2.21M 4s
9250K .......... ....
...... .......... .......... .......... 37% 1.22M 4s
9300K .......... .......... .......... .......... .......... 37% 5.76M 4s
9350K .......... .......... .......... .......... .......... 37% 7.05M 4s
9400K .......... .......... .......... .......... .......... 38% 409K 4s
9450K .......... .......... .......... .......... .......... 38% 182M 4s
9500K .......... .......... .......... .......... .......... 38% 152M 4s
9550K .......... .......... .......... .......... .......... 38% 130M 4s
9600K .......... .......... .......... .......... ........
.. 38% 473K 4s
9650K .......... .......... .......... .......... .......... 39% 8.25M 4s
9700K .......... .......... .......... .......... .......... 39% 241M 4s
9750K .......... .......... .......... .......... .......... 39% 211M 4s
9800K .......... .......... .......... .......... .......... 39% 1021K 4s
9850K .......... .......... .......... .......... .......... 39% 947K 4s
9900K .......... .......... .......... .......... .......... 40% 2.60M 4s
9950K .......... .......... .......... .......... .......... 40% 747K 4s
10000K .......... .......... .......... ..
........ .......... 40% 919K 4s
10050K .......... .......... .......... .......... .......... 40% 2.59M 4s
10100K .......... .......... .......... .......... .......... 40% 796K 4s
10150K .......... .......... .......... .......... .......... 41% 6.04M 4s
10200K .......... .......... .......... .......... .......... 41% 743K 4s
10250K .......... .......... .......... ........
.. .......... 41% 2.77M 4s
10300K .......... .......... .......... .......... .......... 41% 903K 4s
10350K .......... .......... .......... .......... .......... 41% 965K 4s
10400K .......... .......... .......... .......... .......... 42% 2.56M 4s
10450K .......... .......... .......... .......... .......... 42% 745K 4s
10500K .......... .......... .......... .......... .......... 42% 11.0M 4s
10550K ..........
.......... .......... .......... .......... 42% 755K 4s
10600K .......... .......... .......... .......... .......... 42% 2.74M 4s
10650K .......... .......... .......... .......... .......... 43% 948K 4s
10700K .......... .......... .......... .......... .......... 43% 2.76M 4s
10750K .......... .......... .......... .......... .......... 43% 943K 4s
10800K .......... .......... .......... ..
........ .......... 43% 909K 4s
10850K .......... .......... .......... .......... .......... 43% 2.69M 4s
10900K .......... .......... .......... .......... .......... 44% 787K 4s
10950K .......... .......... .......... .......... .......... 44% 6.96M 4s
11000K .......... .......... .......... .......... .......... 44% 774K 4s
11050K .......... .......... .......... .......... .......... 44% 6.95M 4s
11100K ....
...... .......... .......... .......... .......... 44% 782K 4s
11150K .......... .......... .......... .......... .......... 45% 7.18M 4s
11200K .......... .......... .......... .......... .......... 45% 474K 5s
11250K .......... .......... .......... .......... .......... 45% 272M 4s
11300K .......... .......... .......... .......... .......... 45% 1.32M 4s
11350K ..........
.......... .......... .......... .......... 45% 761K 5s
11400K .......... .......... .......... .......... .......... 46% 894K 5s
11450K .......... .......... .......... .......... .......... 46% 1.47M 5s
11500K .......... .......... .......... .......... .......... 46% 911K 5s
11550K ..
........ .......... .......... .......... .......... 46% 754K 5s
11600K .......... .......... .......... .......... .......... 46% 720K 5s
11650K .......... .......... .......... .......... .......... 47% 2.31M 5s
11700K .......... .......... .......... .......... .......... 47% 916K 5s
11750K ..........
.......... .......... .......... .......... 47% 764K 5s
11800K .......... .......... .......... .......... .......... 47% 2.32M 5s
11850K .......... .......... .......... .......... .......... 47% 907K 5s
11900K .......... .......... .......... .......... .......... 48% 769K 5s
11950K .......... .......... .......... ....
...... .......... 48% 2.27M 5s
12000K .......... .......... .......... .......... .......... 48% 712K 5s
12050K .......... .......... .......... .......... .......... 48% 984K 5s
12100K .......... .......... .......... .......... .......... 48% 888K 5s
12150K .......... .......... .......... .......... .......... 49% 2.53M 5s
12200K ........
.. .......... .......... .......... .......... 49% 774K 5s
12250K .......... .......... .......... .......... .......... 49% 2.34M 5s
12300K .......... .......... .......... .......... .......... 49% 913K 5s
12350K .......... .......... .......... .......... .......... 49% 767K 5s
12400K .......... .......... .......... ..
........ .......... 50% 869K 5s
12450K .......... .......... .......... .......... .......... 50% 2.57M 5s
12500K .......... .......... .......... .......... .......... 50% 774K 5s
12550K .......... .......... .......... .......... .......... 50% 2.32M 5s
12600K .......... .......... .......... .......... .......... 51% 919K 5s
12650K ......
.... .......... .......... .......... .......... 51% 944K 5s
12700K .......... .......... .......... .......... .......... 51% 1.48M 5s
12750K .......... .......... .......... .......... .......... 51% 925K 5s
12800K .......... .......... .......... .......... .......... 51% 926K 5s
12850K .......... .......... .......... .......... ......
.... 52% 1.46M 5s
12900K .......... .......... .......... .......... .......... 52% 934K 5s
12950K .......... .......... .......... .......... .......... 52% 931K 5s
13000K .......... .......... .......... .......... .......... 52% 2.65M 5s
13050K .......... .......... .......... .......... .......... 52% 952K 5s
13100K .......... .......... .......... ......
.... .......... 53% 1.37M 5s
13150K .......... .......... .......... .......... .......... 53% 404K 5s
13200K .......... .......... .......... .......... .......... 53% 212M 5s
13250K .......... .......... .......... .......... .......... 53% 2.18M 5s
13300K .......... .......... .......... .......... ....
...... 53% 785K 5s
13350K .......... .......... .......... .......... .......... 54% 912K 5s
13400K .......... .......... .......... .......... .......... 54% 399K 5s
13450K .......... .......... .......... .......... .......... 54% 3.04M 5s
13500K ....
...... .......... .......... .......... .......... 54% 708K 5s
13550K .......... .......... .......... .......... .......... 54% 709K 5s
13600K .......... .......... .......... ..
........ .......... 55% 401K 5s
13650K .......... .......... .......... .......... .......... 55% 708K 5s
13700K .......... .......... .......... .......... .......... 55% 708K 5s
13750K .......... .......... ......
.... .......... .......... 55% 708K 5s
13800K .......... .......... .......... .......... .......... 55% 707K 5s
13850K .......... .......... .......... .......... .......... 56% 709K 5s
13900K .......... ..........
.......... .......... .......... 56% 710K 5s
13950K .......... .......... .......... .......... .......... 56% 708K 5s
14000K .......... .......... .......... .......... .......... 56% 574K 5s
14050K .......... ....
...... .......... .......... .......... 56% 892K 5s
14100K .......... .......... .......... .......... .......... 57% 709K 5s
14150K .......... .......... .......... .......... .......... 57% 711K 5s
14200K .......... .......... ....
...... .......... .......... 57% 703K 5s
14250K .......... .......... .......... .......... .......... 57% 1.32M 5s
14300K .......... .......... .......... .......... .......... 57% 711K 5s
14350K .......... .......... .......... ....
...... .......... 58% 752K 5s
14400K .......... .......... .......... .......... .......... 58% 667K 5s
14450K .......... .......... .......... .......... .......... 58% 760K 5s
14500K .......... .......... .......... .......... ....
...... 58% 711K 5s
14550K .......... .......... .......... .......... .......... 58% 890K 5s
14600K .......... .......... .......... .......... .......... 59% 721K 5s
14650K .......... .......... .......... .......... .......... 59% 928K 5s
14700K .......... ..........
.......... .......... .......... 59% 1.33M 5s
14750K .......... .......... .......... .......... .......... 59% 751K 5s
14800K .......... .......... .......... .......... .......... 59% 708K 5s
14850K .......... .......... .......... .......... ......
.... 60% 713K 5s
14900K .......... .......... .......... .......... .......... 60% 916K 5s
14950K .......... .......... .......... .......... .......... 60% 913K 5s
15000K .......... .......... .......... .......... .......... 60% 1.38M 5s
15050K .......... .......... .......... ........
.. .......... 60% 748K 5s
15100K .......... .......... .......... .......... .......... 61% 343K 5s
15150K .......... .......... .......... ....
...... .......... 61% 906K 5s
15200K .......... .......... .......... .......... .......... 61% 3.18M 5s
15250K .......... .......... .......... .......... .......... 61% 467K 5s
15300K .......... .......... .......... .......... .......... 61% 708K 5s
15350K ..........
.......... .......... .......... .......... 62% 709K 5s
15400K .......... .......... .......... .......... .......... 62% 709K 5s
15450K .......... .......... .......... .......... .......... 62% 691K 5s
15500K ....
...... .......... .......... .......... .......... 62% 411K 5s
15550K .......... .......... .......... .......... .......... 62% 171M 5s
15600K .......... .......... .......... ..
........ .......... 63% 406K 5s
15650K .......... .......... .......... .......... .......... 63% 681K 5s
15700K .......... .......... .......... .......... ....
...... 63% 407K 5s
15750K .......... .......... .......... .......... .......... 63% 706K 5s
15800K .......... .......... .......... .......... .......... 63% 584K 5s
15850K .......... .......... ..
........ .......... .......... 64% 681K 5s
15900K .......... .......... .......... .......... .......... 64% 705K 5s
15950K .......... .......... .......... .......... .......... 64% 451K 5s
16000K .......... .......... .......... .......... .......... 64% 498K 5s
16050K .......... .......... .......... .......... .......... 64% 708K 5s
16100K .......... .......... ........
.. .......... .......... 65% 705K 5s
16150K .......... .......... .......... .......... .......... 65% 709K 5s
16200K .......... .......... .......... .......... .......... 65% 710K 5s
16250K .......... .......... ..
........ .......... .......... 65% 446K 5s
16300K .......... .......... .......... .......... .......... 65% 707K 5s
16350K .......... ........
.. .......... .......... .......... 66% 354K 5s
16400K .......... .......... .......... .......... .......... 66% 352K 5s
16450K .......... .......... .......... .......... .......... 66% 1.52M 5s
16500K .......... ..
........ .......... .......... .......... 66% 354K 5s
16550K .......... .......... .......... .......... ..
........ 66% 353K 5s
16600K .......... .......... .......... .......... .......... 67% 352K 5s
16650K ......
.... .......... .......... .......... .......... 67% 246K 5s
16700K .......... ..........
.......... .......... .......... 67% 337K 5s
16750K .......... .......... .......... .......... .......... 67% 354K 5s
16800K .......... .......... .......... .......... .......... 67% 237K 5s
16850K .......... .......... ..........
.......... .......... 68% 353K 5s
16900K .......... .......... .......... .......... .......... 68% 550K 5s
16950K ..........
.......... .......... .......... .......... 68% 404K 5s
17000K .......... .......... .......... ..........
.......... 68% 357K 5s
17050K .......... .......... .......... .......... .......... 68% 550K 5s
17100K .......... .......... .......... ......
.... .......... 69% 413K 5s
17150K .......... .......... .......... .......... .......... 69% 550K 5s
17200K .......... .......... .......... ..
........ .......... 69% 354K 5s
17250K .......... .......... .......... .......... .......... 69% 448K 5s
17300K .......... .......... .......... .......... ....
...... 69% 633K 5s
17350K .......... .......... .......... .......... .......... 70% 544K 5s
17400K .......... .......... .......... .......... .......... 70% 704K 5s
17450K ......
.... .......... .......... .......... .......... 70% 423K 5s
17500K .......... .......... .......... .......... .......... 70% 538K 5s
17550K .......... ........
.. .......... .......... .......... 70% 707K 5s
17600K .......... .......... .......... .......... .......... 71% 426K 5s
17650K .......... .......... .......... .......... ......
.... 71% 702K 5s
17700K .......... .......... .......... .......... .......... 71% 698K 5s
17750K .......... .......... .......... .......... .......... 71% 542K 5s
17800K .......... .......... ....
...... .......... .......... 71% 707K 5s
17850K .......... .......... .......... .......... .......... 72% 708K 5s
17900K .......... .......... .......... .......... .......... 72% 708K 5s
17950K ..
........ .......... .......... .......... .......... 72% 710K 5s
18000K .......... .......... .......... .......... .......... 72% 449K 5s
18050K .......... .......... .......... .......... ......
.... 72% 710K 5s
18100K .......... .......... .......... .......... .......... 73% 709K 5s
18150K .......... .......... .......... .......... .......... 73% 708K 5s
18200K .......... .......... .......... .......... .......... 73% 1.59M 5s
18250K ......
.... .......... .......... .......... .......... 73% 707K 5s
18300K .......... .......... .......... .......... .......... 73% 710K 5s
18350K .......... .......... .......... .......... .......... 74% 709K 5s
18400K .......... ......
.... .......... .......... .......... 74% 706K 5s
18450K .......... .......... .......... .......... .......... 74% 713K 5s
18500K .......... .......... .......... .......... .......... 74% 711K 5s
18550K .......... .......... ......
.... .......... .......... 74% 712K 5s
18600K .......... .......... .......... .......... .......... 75% 1.03M 5s
18650K .......... .......... .......... .......... .......... 75% 716K 5s
18700K .......... .......... .......... ......
.... .......... 75% 780K 5s
18750K .......... .......... .......... .......... .......... 75% 1.58M 5s
18800K .......... .......... .......... ..
........ .......... 75% 276K 5s
18850K .......... .......... .......... .......... .......... 76% 224M 5s
18900K .......... .......... .......... .......... .......... 76% 715K 5s
18950K .......... .......... .......... .......... .......... 76% 495K 5s
19000K .......... .......... .......... ..........
.......... 76% 707K 5s
19050K .......... .......... .......... .......... .......... 77% 705K 5s
19100K .......... .......... .......... .......... .......... 77% 708K 5s
19150K .......... .......... .......... ....
...... .......... 77% 679K 4s
19200K .......... .......... .......... .......... .......... 77% 707K 4s
19250K .......... .......... .......... .......... .......... 77% 709K 4s
19300K .......... .......... ........
.. .......... .......... 78% 710K 4s
19350K .......... .......... .......... .......... .......... 78% 710K 4s
19400K .......... .......... .......... .......... .......... 78% 709K 4s
19450K .......... .......... .......... ........
.. .......... 78% 712K 4s
19500K .......... .......... .......... .......... .......... 78% 708K 4s
19550K .......... .......... .......... .......... .......... 79% 1.34M 4s
19600K .......... .......... .......... .......... ........
.. 79% 478K 4s
19650K .......... .......... .......... .......... .......... 79% 1.30M 4s
19700K .......... .......... .......... .......... .......... 79% 1.43M 4s
19750K .......... .......... .......... .......... .......... 79% 709K 4s
19800K .......... .......... ....
...... .......... .......... 80% 710K 4s
19850K .......... .......... .......... .......... .......... 80% 711K 4s
19900K .......... .......... .......... .......... .......... 80% 709K 4s
19950K .......... .......... .......... ....
...... .......... 80% 713K 4s
20000K .......... .......... .......... .......... .......... 80% 705K 4s
20050K .......... .......... .......... .......... .......... 81% 715K 4s
20100K .......... .......... .......... .......... .......... 81% 1.25M 4s
20150K ..........
.......... .......... .......... .......... 81% 1.48M 4s
20200K .......... .......... .......... .......... .......... 81% 713K 4s
20250K .......... .......... .......... .......... .......... 81% 716K 4s
20300K .......... .......... .......... ......
.... .......... 82% 712K 4s
20350K .......... .......... .......... .......... .......... 82% 1.24M 4s
20400K .......... .......... .......... .......... .......... 82% 493K 4s
20450K .......... .......... .......... .......... .......... 82% 1.24M 4s
20500K .......... ..
........ .......... .......... .......... 82% 1.50M 4s
20550K .......... .......... .......... .......... .......... 83% 714K 4s
20600K .......... .......... .......... .......... .......... 83% 712K 3s
20650K .......... .......... .......... .......... .......... 83% 1.24M 3s
20700K ....
...... .......... .......... .......... .......... 83% 1.51M 3s
20750K .......... .......... .......... .......... .......... 83% 717K 3s
20800K .......... .......... .......... .......... .......... 84% 706K 3s
20850K .......... .......... .......... .......... ......
.... 84% 714K 3s
20900K .......... .......... .......... .......... .......... 84% 1.25M 3s
20950K .......... .......... .......... .......... .......... 84% 1.51M 3s
21000K .......... .......... .......... .......... .......... 84% 716K 3s
21050K .......... .......... .......... ........
.. .......... 85% 716K 3s
21100K .......... .......... .......... .......... .......... 85% 1.25M 3s
21150K .......... .......... .......... .......... .......... 85% 1.51M 3s
21200K .......... .......... .......... .......... .......... 85% 707K 3s
21250K .......... .......... .......... .......... ......
.... 85% 716K 3s
21300K .......... .......... .......... .......... .......... 86% 1.27M 3s
21350K .......... .......... .......... .......... .......... 86% 349K 3s
21400K ........
.. .......... .......... .......... .......... 86% 1.57M 3s
21450K .......... .......... .......... .......... .......... 86% 1.29M 3s
21500K .......... .......... .......... .......... .......... 86% 708K 3s
21550K .......... .......... .......... .......... .......... 87% 709K 3s
21600K .......... .......... .......... .......... .......... 87% 486K 3s
21650K .......... .......... .......... .......... .......... 87% 1.24M 3s
21700K .......... .......... .......... .......... .......... 87% 725K 3s
21750K ..........
.......... .......... .......... .......... 87% 681K 3s
21800K .......... .......... .......... .......... .......... 88% 977K 3s
21850K .......... .......... .......... .......... .......... 88% 986K 2s
21900K .......... .......... .......... ......
.... .......... 88% 729K 2s
21950K .......... .......... .......... .......... .......... 88% 1.17M 2s
22000K .......... .......... .......... .......... .......... 88% 502K 2s
22050K .......... .......... .......... .......... .......... 89% 1.18M 2s
22100K .......... ..
........ .......... .......... .......... 89% 716K 2s
22150K .......... .......... .......... .......... .......... 89% 1.42M 2s
22200K .......... .......... .......... .......... .......... 89% 725K 2s
22250K .......... .......... .......... .......... .......... 89% 1.28M 2s
22300K ....
...... .......... .......... .......... .......... 90% 714K 2s
22350K .......... .......... .......... .......... .......... 90% 1.39M 2s
22400K .......... .......... .......... .......... .......... 90% 710K 2s
22450K .......... .......... .......... .......... ......
.... 90% 738K 2s
22500K .......... .......... .......... .......... .......... 90% 1.27M 2s
22550K .......... .......... .......... .......... .......... 91% 716K 2s
22600K .......... .......... .......... .......... .......... 91% 1.39M 2s
22650K .......... .......... .......... ........
.. .......... 91% 744K 2s
22700K .......... .......... .......... .......... .......... 91% 1.25M 2s
22750K .......... .......... .......... .......... .......... 91% 1.37M 2s
22800K .......... .......... .......... .......... .......... 92% 717K 2s
22850K .......... .......... .......... .......... ......
.... 92% 735K 2s
22900K .......... .......... .......... .......... .......... 92% 1.28M 2s
22950K .......... .......... .......... .......... .......... 92% 975K 2s
23000K .......... .......... .......... .......... .......... 92% 965K 2s
23050K .......... .......... .......... .......... .......... 93% 1.28M 1s
23100K ....
...... .......... .......... .......... .......... 93% 398K 1s
23150K .......... .......... .......... .......... .......... 93% 270M 1s
23200K .......... .......... .......... .......... ........
.. 93% 319K 1s
23250K .......... .......... .......... .......... .......... 93% 192M 1s
23300K .......... .......... .......... .......... .......... 94% 473K 1s
23350K .......... .......... .......... .......... .......... 94% 565K 1s
23400K ........
.. .......... .......... .......... .......... 94% 694K 1s
23450K .......... .......... .......... .......... .......... 94% 353K 1s
23500K ....
...... .......... .......... .......... .......... 94% 413K 1s
23550K .......... .......... .......... ....
...... .......... 95% 355K 1s
23600K .......... .......... .......... ..
........ .......... 95% 235K 1s
23650K .......... .......... .......... .......... .......... 95% 355K 1s
23700K .......... ..
........ .......... .......... .......... 95% 311K 1s
23750K .......... .......... ......
.... .......... .......... 95% 354K 1s
23800K .......... .......... .......... .......... .......... 96% 354K 1s
23850K ......
.... .......... .......... .......... .......... 96% 351K 1s
23900K .......... .......... .......... ......
.... .......... 96% 354K 1s
23950K .......... .......... .......... .......... .......... 96% 355K 1s
24000K .......... ......
.... .......... .......... .......... 96% 355K 1s
24050K .......... .......... .......... .......... .......... 97% 416K 1s
24100K .......... ..
........ .......... .......... .......... 97% 547K 1s
24150K .......... .......... .......... .......... .......... 97% 416K 1s
24200K ........
.. .......... .......... .......... .......... 97% 545K 1s
24250K .......... .......... .......... .......... .......... 97% 411K 0s
24300K ....
...... .......... .......... .......... .......... 98% 543K 0s
24350K .......... .......... .......... .......... .......... 98% 705K 0s
24400K .......... ......
.... .......... .......... .......... 98% 356K 0s
24450K .......... .......... .......... .......... .......... 98% 707K 0s
24500K .......... .......... ........
.. .......... .......... 98% 448K 0s
24550K .......... .......... .......... .......... .......... 99% 634K 0s
24600K .......... .......... .......... ..........
.......... 99% 548K 0s
24650K .......... .......... .......... .......... .......... 99% 707K 0s
24700K .......... .......... .......... .......... .......... 99% 706K 0s
24750K .......... ........
.. .......... .......... .......... 99% 697K 0s
24800K ... 100% 92.6M=24s
2024-04-02 01:28:50 (1.02 MB/s) - ‘gistemp1200_GHCNv4_ERSSTv5.nc.gz’ saved [25398620/25398620]
<xarray.Dataset> Size: 112MB Dimensions: (lat: 90, lon: 180, time: 1730, nv: 2) Coordinates: * lat (lat) float32 360B -89.0 -87.0 -85.0 -83.0 ... 85.0 87.0 89.0 * lon (lon) float32 720B -179.0 -177.0 -175.0 ... 175.0 177.0 179.0 * time (time) datetime64[ns] 14kB 1880-01-15 1880-02-15 ... 2024-02-15 Dimensions without coordinates: nv Data variables: time_bnds (time, nv) datetime64[ns] 28kB 1880-01-01 ... 2024-03-01 tempanomaly (time, lat, lon) float32 112MB nan nan nan ... 7.88 7.88 7.88 Attributes: title: GISTEMP Surface Temperature Analysis institution: NASA Goddard Institute for Space Studies source: http://data.giss.nasa.gov/gistemp/ Conventions: CF-1.6 history: Created 2024-03-08 11:37:27 by SBBX_to_nc 2.0 - ILAND=1200,...
Remap longitude range from [-180, 180] to [0, 360] for plotting purposes:
ds = ds.assign_coords(lon=((ds.lon + 360) % 360)).sortby('lon')
ds
<xarray.Dataset> Size: 112MB Dimensions: (lat: 90, time: 1730, nv: 2, lon: 180) Coordinates: * lat (lat) float32 360B -89.0 -87.0 -85.0 -83.0 ... 85.0 87.0 89.0 * time (time) datetime64[ns] 14kB 1880-01-15 1880-02-15 ... 2024-02-15 * lon (lon) float32 720B 1.0 3.0 5.0 7.0 ... 353.0 355.0 357.0 359.0 Dimensions without coordinates: nv Data variables: time_bnds (time, nv) datetime64[ns] 28kB 1880-01-01 ... 2024-03-01 tempanomaly (time, lat, lon) float32 112MB nan nan nan ... 7.88 7.88 7.88 Attributes: title: GISTEMP Surface Temperature Analysis institution: NASA Goddard Institute for Space Studies source: http://data.giss.nasa.gov/gistemp/ Conventions: CF-1.6 history: Created 2024-03-08 11:37:27 by SBBX_to_nc 2.0 - ILAND=1200,...
Compute observed trends
Include only full seasons from 1979 through 2012:
obs_seasons = ds.sel(time=slice("1979", "2012")).resample(time="QS-DEC").mean("time")
obs_seasons = obs_seasons.sel(time=slice("1979", "2012")).load()
obs_winter_seasons = obs_seasons.sel(
time=obs_seasons.time.where(obs_seasons.time.dt.month == 12, drop=True)
)
obs_winter_seasons
<xarray.Dataset> Size: 2MB Dimensions: (lat: 90, time: 34, lon: 180) Coordinates: * lat (lat) float32 360B -89.0 -87.0 -85.0 -83.0 ... 85.0 87.0 89.0 * lon (lon) float32 720B 1.0 3.0 5.0 7.0 ... 353.0 355.0 357.0 359.0 * time (time) datetime64[ns] 272B 1979-12-01 1980-12-01 ... 2012-12-01 Data variables: tempanomaly (time, lat, lon) float32 2MB 0.5367 0.5367 0.5367 ... 7.04 7.04 Attributes: title: GISTEMP Surface Temperature Analysis institution: NASA Goddard Institute for Space Studies source: http://data.giss.nasa.gov/gistemp/ Conventions: CF-1.6 history: Created 2024-03-08 11:37:27 by SBBX_to_nc 2.0 - ILAND=1200,...
And compute observed winter trends:
obs_winter_trends = linear_trend(
obs_winter_seasons.chunk({"lat": 20, "lon": 20, "time": -1})
).load() * len(obs_winter_seasons.time)
obs_winter_trends
<xarray.Dataset> Size: 131kB Dimensions: (lat: 90, lon: 180) Coordinates: * lat (lat) float32 360B -89.0 -87.0 -85.0 -83.0 ... 85.0 87.0 89.0 * lon (lon) float32 720B 1.0 3.0 5.0 7.0 ... 353.0 355.0 357.0 359.0 Data variables: tempanomaly (lat, lon) float64 130kB 1.407 1.407 1.407 ... 5.587 5.587
Plotting Figure 4
Global maps of historical (1979 - 2012) boreal winter (DJF) surface air trends:
contour_levels = [-6, -5, -4, -3, -2, -1.5, -1, -0.5, 0, 0.5, 1, 1.5, 2, 3, 4, 5, 6]
color_map = cmaps.ncl_default
def make_map_plot(nplot_rows, nplot_cols, plot_index, data, plot_label):
""" Create a single map subplot. """
ax = plt.subplot(nplot_rows, nplot_cols, plot_index, projection = ccrs.Robinson(central_longitude = 180))
cplot = plt.contourf(lons, lats, data,
levels = contour_levels,
cmap = color_map,
extend = 'both',
transform = ccrs.PlateCarree())
ax.coastlines(color = 'grey')
ax.text(0.01, 0.01, plot_label, fontsize = 14, transform = ax.transAxes)
return cplot, ax
%%time
# Generate plot (may take a while as many individual maps are generated)
numPlotRows = 8
numPlotCols = 4
figWidth = 20
figHeight = 30
fig, axs = plt.subplots(numPlotRows, numPlotCols, figsize=(figWidth,figHeight))
lats = winter_trends.lat
lons = winter_trends.lon
# Create ensemble member plots
for ensemble_index in range(30):
plot_data = winter_trends.isel(member_id = ensemble_index)
plot_index = ensemble_index + 1
plot_label = str(plot_index)
plotRow = ensemble_index // numPlotCols
plotCol = ensemble_index % numPlotCols
# Retain axes objects for figure colorbar
cplot, axs[plotRow, plotCol] = make_map_plot(numPlotRows, numPlotCols, plot_index, plot_data, plot_label)
# Create plots for the ensemble mean, observations, and a figure color bar.
cplot, axs[7,2] = make_map_plot(numPlotRows, numPlotCols, 31, winter_trends_mean, 'EM')
lats = obs_winter_trends.lat
lons = obs_winter_trends.lon
cplot, axs[7,3] = make_map_plot(numPlotRows, numPlotCols, 32, obs_winter_trends.tempanomaly, 'OBS')
cbar = fig.colorbar(cplot, ax=axs, orientation='horizontal', shrink = 0.7, pad = 0.02)
cbar.ax.set_title('1979-2012 DJF surface air temperature trends (K/34 years)', fontsize = 16)
cbar.set_ticks(contour_levels)
cbar.set_ticklabels(contour_levels)
CPU times: user 1min 36s, sys: 4.97 s, total: 1min 41s
Wall time: 1min 35s
Close our client:
client.close()
Summary
In this notebook, we used CESM LENS data hosted on AWS to recreate two key figures in the paper that describes the project.
What’s next?
More example workflows using these datasets may be added in the future.