You can run this notebook in a live session Binder or view it on Github.

Table of Contents

  • 1  Compare weighted and unweighted mean temperature

      • 1.0.1  Data

      • 1.0.2  Creating weights

      • 1.0.3  Weighted mean

      • 1.0.4  Plot: comparison with unweighted mean

Compare weighted and unweighted mean temperature

Author: Mathias Hauser

We use the air_temperature example dataset to calculate the area-weighted temperature over its domain. This dataset has a regular latitude/ longitude grid, thus the grid cell area decreases towards the pole. For this grid we can use the cosine of the latitude as proxy for the grid cell area.

[1]:
%matplotlib inline

import cartopy.crs as ccrs
import matplotlib.pyplot as plt
import numpy as np

import xarray as xr

Data

Load the data, convert to celsius, and resample to daily values

[2]:
ds = xr.tutorial.load_dataset("air_temperature")

# to celsius
air = ds.air - 273.15

# resample from 6-hourly to daily values
air = air.resample(time="D").mean()

air
---------------------------------------------------------------------------
PermissionError                           Traceback (most recent call last)
File /usr/lib/python3/dist-packages/pooch/utils.py:262, in make_local_storage(path, env)
    258 if action == "create":
    259     # When running in parallel, it's possible that multiple jobs will
    260     # try to create the path at the same time. Use exist_ok to avoid
    261     # raising an error.
--> 262     os.makedirs(path, exist_ok=True)
    263 else:

File /usr/lib/python3.13/os.py:217, in makedirs(name, mode, exist_ok)
    216 try:
--> 217     makedirs(head, exist_ok=exist_ok)
    218 except FileExistsError:
    219     # Defeats race condition when another thread created the path

File /usr/lib/python3.13/os.py:217, in makedirs(name, mode, exist_ok)
    216 try:
--> 217     makedirs(head, exist_ok=exist_ok)
    218 except FileExistsError:
    219     # Defeats race condition when another thread created the path

File /usr/lib/python3.13/os.py:227, in makedirs(name, mode, exist_ok)
    226 try:
--> 227     mkdir(name, mode)
    228 except OSError:
    229     # Cannot rely on checking for EEXIST, since the operating system
    230     # could give priority to other errors like EACCES or EROFS

PermissionError: [Errno 13] Permission denied: '/sbuild-nonexistent'

The above exception was the direct cause of the following exception:

PermissionError                           Traceback (most recent call last)
Cell In[2], line 1
----> 1 ds = xr.tutorial.load_dataset("air_temperature")
      3 # to celsius
      4 air = ds.air - 273.15

File /usr/lib/python3/dist-packages/xarray/tutorial.py:213, in load_dataset(*args, **kwargs)
    176 def load_dataset(*args, **kwargs) -> Dataset:
    177     """
    178     Open, load into memory, and close a dataset from the online repository
    179     (requires internet).
   (...)
    211     load_dataset
    212     """
--> 213     with open_dataset(*args, **kwargs) as ds:
    214         return ds.load()

File /usr/lib/python3/dist-packages/xarray/tutorial.py:165, in open_dataset(name, cache, cache_dir, engine, **kws)
    162 downloader = pooch.HTTPDownloader(headers=headers)
    164 # retrieve the file
--> 165 filepath = pooch.retrieve(
    166     url=url, known_hash=None, path=cache_dir, downloader=downloader
    167 )
    168 ds = _open_dataset(filepath, engine=engine, **kws)
    169 if not cache:

File /usr/lib/python3/dist-packages/pooch/core.py:227, in retrieve(url, known_hash, fname, path, processor, downloader, progressbar)
    222 action, verb = download_action(full_path, known_hash)
    224 if action in ("download", "update"):
    225     # We need to write data, so create the local data directory if it
    226     # doesn't already exist.
--> 227     make_local_storage(path)
    229     get_logger().info(
    230         "%s data from '%s' to file '%s'.",
    231         verb,
    232         url,
    233         str(full_path),
    234     )
    236     if downloader is None:

File /usr/lib/python3/dist-packages/pooch/utils.py:276, in make_local_storage(path, env)
    272 if env is not None:
    273     message.append(
    274         f"Use environment variable '{env}' to specify a different location."
    275     )
--> 276 raise PermissionError(" ".join(message)) from error

PermissionError: [Errno 13] Permission denied: '/sbuild-nonexistent' | Pooch could not create data cache folder '/sbuild-nonexistent/.cache/xarray_tutorial_data'. Will not be able to download data files.

Plot the first timestep:

[3]:
projection = ccrs.LambertConformal(central_longitude=-95, central_latitude=45)

f, ax = plt.subplots(subplot_kw=dict(projection=projection))

air.isel(time=0).plot(transform=ccrs.PlateCarree(), cbar_kwargs=dict(shrink=0.7))
ax.coastlines()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[3], line 5
      1 projection = ccrs.LambertConformal(central_longitude=-95, central_latitude=45)
      3 f, ax = plt.subplots(subplot_kw=dict(projection=projection))
----> 5 air.isel(time=0).plot(transform=ccrs.PlateCarree(), cbar_kwargs=dict(shrink=0.7))
      6 ax.coastlines()

NameError: name 'air' is not defined
../_images/examples_area_weighted_temperature_6_1.png

Creating weights

For a rectangular grid the cosine of the latitude is proportional to the grid cell area.

[4]:
weights = np.cos(np.deg2rad(air.lat))
weights.name = "weights"
weights
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[4], line 1
----> 1 weights = np.cos(np.deg2rad(air.lat))
      2 weights.name = "weights"
      3 weights

NameError: name 'air' is not defined

Weighted mean

[5]:
air_weighted = air.weighted(weights)
air_weighted
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[5], line 1
----> 1 air_weighted = air.weighted(weights)
      2 air_weighted

NameError: name 'air' is not defined
[6]:
weighted_mean = air_weighted.mean(("lon", "lat"))
weighted_mean
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[6], line 1
----> 1 weighted_mean = air_weighted.mean(("lon", "lat"))
      2 weighted_mean

NameError: name 'air_weighted' is not defined

Plot: comparison with unweighted mean

Note how the weighted mean temperature is higher than the unweighted.

[7]:
weighted_mean.plot(label="weighted")
air.mean(("lon", "lat")).plot(label="unweighted")

plt.legend()
---------------------------------------------------------------------------
NameError                                 Traceback (most recent call last)
Cell In[7], line 1
----> 1 weighted_mean.plot(label="weighted")
      2 air.mean(("lon", "lat")).plot(label="unweighted")
      4 plt.legend()

NameError: name 'weighted_mean' is not defined