logo

Plot Time Series of CAMS Data#

This tutorial demonstrates how to plot time series of data from the Copernicus Atmosphere Monitoring Service (CAMS). The example focusses on CO2, and we will visualise the “Keeling Curve” of global average increases in CO2 from the last decades.

Run the tutorial via free cloud platforms: Binder Kaggle Colab

Install and import packages#

!pip install cdsapi
# CDS API
import cdsapi

# Libraries for reading and working with multidimensional arrays
import numpy as np
import xarray as xr

# Library for plotting and visualising data
%matplotlib inline
import matplotlib.pyplot as plt

# Disable warnings for data download via API
import urllib3 
urllib3.disable_warnings()

Data access and preprocessing#

Download CAMS global reanalysis data#

Copy your API key into the code cell below, replacing ####### with your key. (Remember, to access data from the ADS, you will need first to register/login https://ads-beta.atmosphere.copernicus.eu/ and obtain an API key from https://ads-beta.atmosphere.copernicus.eu/how-to-api.)

URL = 'https://ads-beta.atmosphere.copernicus.eu/api'

# Replace the hashtags with your key:
KEY = '##################################'

Here we specify a data directory into which we will download our data and all output files that we will generate:

DATADIR = '.'

For this tutorial, we will use CAMS global greenhouse gas reanalysis (EGG4) data, monthly averaged fields version. The code below shows the subset characteristics that we will extract from this dataset as an API request.

Note

Before running this code, ensure that you have accepted the terms and conditions. This is something you only need to do once for each CAMS dataset. You will find the option to do this by selecting the dataset in the ADS, then scrolling to the end of the Download data tab.

dataset = "cams-global-ghg-reanalysis-egg4-monthly"
request = {
    'variable': ['co2_column_mean_molar_fraction'],
    'year': ['2003', '2004', '2005', '2006', 
             '2007', '2008', '2009', '2010', 
             '2011', '2012', '2013', '2014', 
             '2015', '2016', '2017', '2018', 
             '2019', '2020'],
    'month': ['01', '02', '03', '04', '05', '06', 
              '07', '08', '09', '10', '11', '12'],
    'product_type': ['monthly_mean'],
    'data_format': 'netcdf'
}

client = cdsapi.Client(url=URL, key=KEY)
client.retrieve(dataset, request).download(
    f'{DATADIR}/CO2_2003-2020.nc')
2024-09-12 14:14:30,224 INFO Request ID is f2070345-f2f8-46ea-9638-96715107bffd
2024-09-12 14:14:30,375 INFO status has been updated to accepted
2024-09-12 14:14:32,030 INFO status has been updated to running
2024-09-12 14:14:50,916 INFO Creating download object as as_source with files:
['data_allhours_sfc.nc']
2024-09-12 14:14:50,917 INFO status has been updated to successful
'./CO2_2003-2020.nc'

Read and inspect data#

Read the data into an Xarray dataset:

fn = f'{DATADIR}/CO2_2003-2020.nc'
ds = xr.open_dataset(fn)
ds
<xarray.Dataset> Size: 100MB
Dimensions:     (valid_time: 216, latitude: 241, longitude: 480)
Coordinates:
  * valid_time  (valid_time) datetime64[ns] 2kB 2003-01-01 ... 2020-12-01
  * latitude    (latitude) float64 2kB 90.0 89.25 88.5 ... -88.5 -89.25 -90.0
  * longitude   (longitude) float64 4kB 0.0 0.75 1.5 2.25 ... 357.8 358.5 359.2
Data variables:
    tcco2       (valid_time, latitude, longitude) float32 100MB ...
Attributes:
    GRIB_centre:             ecmf
    GRIB_centreDescription:  European Centre for Medium-Range Weather Forecasts
    GRIB_subCentre:          0
    Conventions:             CF-1.7
    institution:             European Centre for Medium-Range Weather Forecasts
    history:                 2024-09-12T14:14 GRIB to CDM+CF via cfgrib-0.9.1...

Spatial aggregation#

We would like to visualise this data not in maps, but as a one dimensional time series of global average values. To do this, we will first need to aggregate the data spatially to create a single global average at each time step.

In order to aggregate over the latitudinal dimension, we need to take into account the variation in area as a function of latitude. We will do this using the cosine of the latitude as a proxy:

weights = np.cos(np.deg2rad(ds.latitude))
weights.name = "weights"
ds_weighted = ds.weighted(weights)

Now we can average over both the longitude and latitude dimensions:

# Average (mean) over the latitudinal axis
co_ds = ds_weighted.mean(dim=["latitude", "longitude"])

Create xarray Data Array from Dataset object#

Here we create an Xarray Data Array object containing the CO2 variable.

co = co_ds['tcco2']

Plot time series of global CO#

Now we can plot the time series of globally averaged CO2 data over time.

Simple plot using xarray#

The easiest way to plot data in an Xarray Data Array object is to use Xarray’s own plotting functionality.

co.plot()
[<matplotlib.lines.Line2D at 0x790bc8eeabf0>]
_images/46bc0d2a8631af1bd2920c9c33b4089c0b527122bf8bd37b9b611495507e5a35.png

In this plot of monthly averaged CO2 we can see the seasonal variation and yearly increase in global CO2 over the last decades.

Customised plot using matplotlib#

In this example we use the Matplotlib library to create the same plot as above, with a few customisations

fig, ax = plt.subplots(1, 1, figsize = (9, 6)) # Set size and dimensions of figure

ax.set_title('CO2 global time series', fontsize=12) # Set figure title
ax.set_ylabel('CO2 column-mean molar fraction (ppm)') # Set Y axis title
ax.set_xlabel('Year') # Set X axis title
ax.grid(linewidth=1, color='gray', alpha=0.5, linestyle='--') # Include gridlines
ax.plot(co.valid_time, co) # Plot the data

fig.savefig(f'{DATADIR}/CAMS_CO2_reanalysis.png') # Save the figure
_images/2b66f6d2eff7e2a6105d555f636f6f7a4bd547ac2b0613799d49802e144e2356.png