Group project: The Climate System¶

Ayla Akgün and Sebastian Wörz

In [1]:
# Import the tools we are going to need today:
import matplotlib.pyplot as plt  # plotting library
import numpy as np  # numerical library
import xarray as xr  # netCDF library
import pandas as pd  # tabular library
import cartopy  # Map projections libary
import cartopy.crs as ccrs  # Projections list
# Some defaults:
plt.rcParams['figure.figsize'] = (12, 5)  # Default plot size

Part 1 - temperature climatology¶

Open the ERA5 temperature data:

In [2]:
ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_t2m.nc')
ds
Out[2]:
<xarray.Dataset>
Dimensions:    (longitude: 480, latitude: 241, time: 480)
Coordinates:
  * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
  * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
  * time       (time) datetime64[ns] 1979-01-01 1979-02-01 ... 2018-12-01
Data variables:
    t2m        (time, latitude, longitude) float32 ...
Attributes:
    Conventions:  CF-1.6
    history:      2019-11-18 09:36:58 GMT by grib_to_netcdf-2.14.0: /opt/ecmw...
xarray.Dataset
    • longitude: 480
    • latitude: 241
    • time: 480
    • longitude
      (longitude)
      float32
      -179.6 -178.9 ... 178.9 179.6
      units :
      degrees_east
      long_name :
      longitude
      array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
            dtype=float32)
    • latitude
      (latitude)
      float32
      90.0 89.25 88.5 ... -89.25 -90.0
      units :
      degrees_north
      long_name :
      latitude
      array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
    • time
      (time)
      datetime64[ns]
      1979-01-01 ... 2018-12-01
      long_name :
      time
      array(['1979-01-01T00:00:00.000000000', '1979-02-01T00:00:00.000000000',
             '1979-03-01T00:00:00.000000000', ..., '2018-10-01T00:00:00.000000000',
             '2018-11-01T00:00:00.000000000', '2018-12-01T00:00:00.000000000'],
            dtype='datetime64[ns]')
    • t2m
      (time, latitude, longitude)
      float32
      ...
      units :
      K
      long_name :
      2 metre temperature
      [55526400 values with dtype=float32]
    • longitude
      PandasIndex
      PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
             -174.375, -173.625, -172.875,
             ...
              172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
              178.125,  178.875,  179.625],
            dtype='float32', name='longitude', length=480))
    • latitude
      PandasIndex
      PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
              83.25,
             ...
             -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
              -90.0],
            dtype='float32', name='latitude', length=241))
    • time
      PandasIndex
      PandasIndex(DatetimeIndex(['1979-01-01', '1979-02-01', '1979-03-01', '1979-04-01',
                     '1979-05-01', '1979-06-01', '1979-07-01', '1979-08-01',
                     '1979-09-01', '1979-10-01',
                     ...
                     '2018-03-01', '2018-04-01', '2018-05-01', '2018-06-01',
                     '2018-07-01', '2018-08-01', '2018-09-01', '2018-10-01',
                     '2018-11-01', '2018-12-01'],
                    dtype='datetime64[ns]', name='time', length=480, freq=None))
  • Conventions :
    CF-1.6
    history :
    2019-11-18 09:36:58 GMT by grib_to_netcdf-2.14.0: /opt/ecmwf/eccodes/bin/grib_to_netcdf -o /cache/data7/adaptor.mars.internal-1574069554.2755394-7634-27-3cce65d0-8d4e-4274-8d69-b5ccb304cc7f.nc /cache/tmp/3cce65d0-8d4e-4274-8d69-b5ccb304cc7f-adaptor.mars.internal-1574069554.2763371-7634-8-tmp.grib

Plot three global maps:

  • Compute and plot the temporal mean temperature $\overline{T}$ for the entire period (unit °C)
  • Compute and plot $\overline{T^{*}}$ (see lesson), the zonal anomaly map of average temperature.
  • Compute and plot the monthly average temperature for each month $\overline{T_M}$ (annual cycle). I expect a variable of dimensions (month: 12, latitude: 241, longitude: 480). Hint: remember the .groupby() command we learned in the lesson. Now plot the average monthly temperature range, i.e. $\overline{T_M}max$ - $\overline{T_M}min$ on a map.

Temporal mean temperature $\overline{T}$ within the period 1978-2008¶

In [3]:
t2c_tavg = ds.t2m.mean(dim='time')- 273.15
t2c_tavg
Out[3]:
<xarray.DataArray 't2m' (latitude: 241, longitude: 480)>
array([[-13.922974, -13.922974, -13.922974, ..., -13.922974, -13.922974,
        -13.922974],
       [-13.990753, -13.994385, -13.998108, ..., -13.984863, -13.986542,
        -13.98822 ],
       [-14.009247, -14.012207, -14.016663, ..., -14.00061 , -14.003601,
        -14.006378],
       ...,
       [-45.326035, -45.314377, -45.29866 , ..., -45.36418 , -45.35118 ,
        -45.338287],
       [-45.98726 , -45.973145, -45.958908, ..., -46.055054, -46.02884 ,
        -46.00374 ],
       [-45.42125 , -45.42125 , -45.42125 , ..., -45.42125 , -45.42125 ,
        -45.42125 ]], dtype=float32)
Coordinates:
  * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
  * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
xarray.DataArray
't2m'
  • latitude: 241
  • longitude: 480
  • -13.92 -13.92 -13.92 -13.92 -13.92 ... -45.42 -45.42 -45.42 -45.42
    array([[-13.922974, -13.922974, -13.922974, ..., -13.922974, -13.922974,
            -13.922974],
           [-13.990753, -13.994385, -13.998108, ..., -13.984863, -13.986542,
            -13.98822 ],
           [-14.009247, -14.012207, -14.016663, ..., -14.00061 , -14.003601,
            -14.006378],
           ...,
           [-45.326035, -45.314377, -45.29866 , ..., -45.36418 , -45.35118 ,
            -45.338287],
           [-45.98726 , -45.973145, -45.958908, ..., -46.055054, -46.02884 ,
            -46.00374 ],
           [-45.42125 , -45.42125 , -45.42125 , ..., -45.42125 , -45.42125 ,
            -45.42125 ]], dtype=float32)
    • longitude
      (longitude)
      float32
      -179.6 -178.9 ... 178.9 179.6
      units :
      degrees_east
      long_name :
      longitude
      array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
            dtype=float32)
    • latitude
      (latitude)
      float32
      90.0 89.25 88.5 ... -89.25 -90.0
      units :
      degrees_north
      long_name :
      latitude
      array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
    • longitude
      PandasIndex
      PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
             -174.375, -173.625, -172.875,
             ...
              172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
              178.125,  178.875,  179.625],
            dtype='float32', name='longitude', length=480))
    • latitude
      PandasIndex
      PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
              83.25,
             ...
             -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
              -90.0],
            dtype='float32', name='latitude', length=241))
In [4]:
ax = plt.axes(projection=ccrs.Robinson())
t2c_tavg.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), vmin=-40, vmax=20, levels=7, cbar_kwargs={'label': '°C'})
ax.coastlines(); ax.gridlines()
ax.set_title(r'Mean 2m air temperature $\overline{T}$, ERA5 1979-2018');
No description has been provided for this image

Zonal anomaly map of average temperature $\overline{T^{*}}$¶

In [5]:
t2c_tzonal = ds.t2m.mean(dim='longitude').mean(dim='time')- 273.15
t2c_tavg_dep = t2c_tavg - t2c_tzonal
t2c_tavg_dep
Out[5]:
<xarray.DataArray 't2m' (latitude: 241, longitude: 480)>
array([[ 0.        ,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.        ],
       [-0.08425903, -0.08789062, -0.09161377, ..., -0.07836914,
        -0.08004761, -0.08172607],
       [-0.14056396, -0.14352417, -0.14797974, ..., -0.13192749,
        -0.13491821, -0.13769531],
       ...,
       [ 0.09609985,  0.10775757,  0.12347412, ...,  0.05795288,
         0.07095337,  0.08384705],
       [-0.47961426, -0.46549988, -0.45126343, ..., -0.54740906,
        -0.52119446, -0.49609375],
       [ 0.        ,  0.        ,  0.        , ...,  0.        ,
         0.        ,  0.        ]], dtype=float32)
Coordinates:
  * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
  * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
xarray.DataArray
't2m'
  • latitude: 241
  • longitude: 480
  • 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0 ... 0.0 0.0 0.0 0.0 0.0 0.0 0.0 0.0
    array([[ 0.        ,  0.        ,  0.        , ...,  0.        ,
             0.        ,  0.        ],
           [-0.08425903, -0.08789062, -0.09161377, ..., -0.07836914,
            -0.08004761, -0.08172607],
           [-0.14056396, -0.14352417, -0.14797974, ..., -0.13192749,
            -0.13491821, -0.13769531],
           ...,
           [ 0.09609985,  0.10775757,  0.12347412, ...,  0.05795288,
             0.07095337,  0.08384705],
           [-0.47961426, -0.46549988, -0.45126343, ..., -0.54740906,
            -0.52119446, -0.49609375],
           [ 0.        ,  0.        ,  0.        , ...,  0.        ,
             0.        ,  0.        ]], dtype=float32)
    • longitude
      (longitude)
      float32
      -179.6 -178.9 ... 178.9 179.6
      units :
      degrees_east
      long_name :
      longitude
      array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
            dtype=float32)
    • latitude
      (latitude)
      float32
      90.0 89.25 88.5 ... -89.25 -90.0
      units :
      degrees_north
      long_name :
      latitude
      array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
    • longitude
      PandasIndex
      PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
             -174.375, -173.625, -172.875,
             ...
              172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
              178.125,  178.875,  179.625],
            dtype='float32', name='longitude', length=480))
    • latitude
      PandasIndex
      PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
              83.25,
             ...
             -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
              -90.0],
            dtype='float32', name='latitude', length=241))
In [6]:
ax = plt.axes(projection=ccrs.Robinson())
t2c_tavg_dep.plot.imshow(ax=ax, transform=ccrs.PlateCarree(),cbar_kwargs={'label': '°C'})
ax.coastlines(); ax.gridlines()
ax.set_title(r'Zonal anomaly of average temperature $\overline{T^{*}}$, ERA5 1979-2018');
No description has been provided for this image

Monthly average temperature $\overline{T_M}$¶

In [7]:
t2c_mavg = ds.t2m.groupby('time.month').mean()-275
t2c_mavg
Out[7]:
<xarray.DataArray 't2m' (month: 12, latitude: 241, longitude: 480)>
array([[[-26.898651, -26.898651, -26.898651, ..., -26.898651,
         -26.898651, -26.898651],
        [-27.142532, -27.148804, -27.15567 , ..., -27.134445,
         -27.136276, -27.13887 ],
        [-27.206345, -27.210083, -27.217972, ..., -27.195847,
         -27.198807, -27.202667],
        ...,
        [-31.23059 , -31.211578, -31.199875, ..., -31.280273,
         -31.26889 , -31.24968 ],
        [-30.777512, -30.759598, -30.741913, ..., -30.835281,
         -30.814697, -30.794846],
        [-29.877808, -29.877808, -29.877808, ..., -29.877808,
         -29.877808, -29.877808]],

       [[-27.502472, -27.502472, -27.502472, ..., -27.502472,
         -27.502472, -27.502472],
        [-27.739822, -27.745926, -27.752731, ..., -27.731232,
         -27.733429, -27.735916],
        [-27.865067, -27.868332, -27.875763, ..., -27.855911,
         -27.85852 , -27.861862],
...
        [-38.64937 , -38.63452 , -38.625366, ..., -38.688843,
         -38.679962, -38.664352],
        [-38.465866, -38.450073, -38.434235, ..., -38.52112 ,
         -38.501907, -38.482834],
        [-37.682495, -37.682495, -37.682495, ..., -37.682495,
         -37.682495, -37.682495]],

       [[-25.453735, -25.453735, -25.453735, ..., -25.453735,
         -25.453735, -25.453735],
        [-25.62558 , -25.632034, -25.638794, ..., -25.615723,
         -25.6185  , -25.621307],
        [-25.75473 , -25.758759, -25.76677 , ..., -25.743195,
         -25.746826, -25.750778],
        ...,
        [-31.329712, -31.312134, -31.30362 , ..., -31.37407 ,
         -31.36502 , -31.34758 ],
        [-30.678802, -30.6613  , -30.643356, ..., -30.73526 ,
         -30.715652, -30.69632 ],
        [-29.62297 , -29.62297 , -29.62297 , ..., -29.62297 ,
         -29.62297 , -29.62297 ]]], dtype=float32)
Coordinates:
  * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
  * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
  * month      (month) int64 1 2 3 4 5 6 7 8 9 10 11 12
xarray.DataArray
't2m'
  • month: 12
  • latitude: 241
  • longitude: 480
  • -26.9 -26.9 -26.9 -26.9 -26.9 ... -29.62 -29.62 -29.62 -29.62 -29.62
    array([[[-26.898651, -26.898651, -26.898651, ..., -26.898651,
             -26.898651, -26.898651],
            [-27.142532, -27.148804, -27.15567 , ..., -27.134445,
             -27.136276, -27.13887 ],
            [-27.206345, -27.210083, -27.217972, ..., -27.195847,
             -27.198807, -27.202667],
            ...,
            [-31.23059 , -31.211578, -31.199875, ..., -31.280273,
             -31.26889 , -31.24968 ],
            [-30.777512, -30.759598, -30.741913, ..., -30.835281,
             -30.814697, -30.794846],
            [-29.877808, -29.877808, -29.877808, ..., -29.877808,
             -29.877808, -29.877808]],
    
           [[-27.502472, -27.502472, -27.502472, ..., -27.502472,
             -27.502472, -27.502472],
            [-27.739822, -27.745926, -27.752731, ..., -27.731232,
             -27.733429, -27.735916],
            [-27.865067, -27.868332, -27.875763, ..., -27.855911,
             -27.85852 , -27.861862],
    ...
            [-38.64937 , -38.63452 , -38.625366, ..., -38.688843,
             -38.679962, -38.664352],
            [-38.465866, -38.450073, -38.434235, ..., -38.52112 ,
             -38.501907, -38.482834],
            [-37.682495, -37.682495, -37.682495, ..., -37.682495,
             -37.682495, -37.682495]],
    
           [[-25.453735, -25.453735, -25.453735, ..., -25.453735,
             -25.453735, -25.453735],
            [-25.62558 , -25.632034, -25.638794, ..., -25.615723,
             -25.6185  , -25.621307],
            [-25.75473 , -25.758759, -25.76677 , ..., -25.743195,
             -25.746826, -25.750778],
            ...,
            [-31.329712, -31.312134, -31.30362 , ..., -31.37407 ,
             -31.36502 , -31.34758 ],
            [-30.678802, -30.6613  , -30.643356, ..., -30.73526 ,
             -30.715652, -30.69632 ],
            [-29.62297 , -29.62297 , -29.62297 , ..., -29.62297 ,
             -29.62297 , -29.62297 ]]], dtype=float32)
    • longitude
      (longitude)
      float32
      -179.6 -178.9 ... 178.9 179.6
      units :
      degrees_east
      long_name :
      longitude
      array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
            dtype=float32)
    • latitude
      (latitude)
      float32
      90.0 89.25 88.5 ... -89.25 -90.0
      units :
      degrees_north
      long_name :
      latitude
      array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
    • month
      (month)
      int64
      1 2 3 4 5 6 7 8 9 10 11 12
      array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12], dtype=int64)
    • longitude
      PandasIndex
      PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
             -174.375, -173.625, -172.875,
             ...
              172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
              178.125,  178.875,  179.625],
            dtype='float32', name='longitude', length=480))
    • latitude
      PandasIndex
      PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
              83.25,
             ...
             -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
              -90.0],
            dtype='float32', name='latitude', length=241))
    • month
      PandasIndex
      PandasIndex(Index([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], dtype='int64', name='month'))
In [8]:
t2c_mavg_global= t2c_mavg.mean(dim='longitude').mean(dim='latitude')
t2c_mavg_global.plot()
plt.title(r'Monthly average temperature $\overline{T_M}$, ERA5 1979-2018');
plt.ylabel('t2m in °C');
No description has been provided for this image

Average monthly temperature range, $\overline{T_M}max$ - $\overline{T_M}min$¶

In [9]:
t2c_mmax= ds.t2m.groupby('time.month').max()-275
t2c_mmin= ds.t2m.groupby('time.month').min()-275
t2c_mrange = (t2c_mmax - t2c_mmin).mean(dim='month')
t2c_mrange
Out[9]:
<xarray.DataArray 't2m' (latitude: 241, longitude: 480)>
array([[9.475941 , 9.475941 , 9.475941 , ..., 9.475941 , 9.475941 ,
        9.475941 ],
       [9.293666 , 9.293369 , 9.2930765, ..., 9.297927 , 9.296161 ,
        9.294402 ],
       [9.1065445, 9.103459 , 9.10052  , ..., 9.116967 , 9.114472 ,
        9.110358 ],
       ...,
       [8.9673   , 8.970679 , 8.968621 , ..., 8.965977 , 8.962598 ,
        8.9651   ],
       [9.140912 , 9.13636  , 9.132392 , ..., 9.181744 , 9.16412  ,
        9.147373 ],
       [9.888969 , 9.888969 , 9.888969 , ..., 9.888969 , 9.888969 ,
        9.888969 ]], dtype=float32)
Coordinates:
  * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
  * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
xarray.DataArray
't2m'
  • latitude: 241
  • longitude: 480
  • 9.476 9.476 9.476 9.476 9.476 9.476 ... 9.889 9.889 9.889 9.889 9.889
    array([[9.475941 , 9.475941 , 9.475941 , ..., 9.475941 , 9.475941 ,
            9.475941 ],
           [9.293666 , 9.293369 , 9.2930765, ..., 9.297927 , 9.296161 ,
            9.294402 ],
           [9.1065445, 9.103459 , 9.10052  , ..., 9.116967 , 9.114472 ,
            9.110358 ],
           ...,
           [8.9673   , 8.970679 , 8.968621 , ..., 8.965977 , 8.962598 ,
            8.9651   ],
           [9.140912 , 9.13636  , 9.132392 , ..., 9.181744 , 9.16412  ,
            9.147373 ],
           [9.888969 , 9.888969 , 9.888969 , ..., 9.888969 , 9.888969 ,
            9.888969 ]], dtype=float32)
    • longitude
      (longitude)
      float32
      -179.6 -178.9 ... 178.9 179.6
      units :
      degrees_east
      long_name :
      longitude
      array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
            dtype=float32)
    • latitude
      (latitude)
      float32
      90.0 89.25 88.5 ... -89.25 -90.0
      units :
      degrees_north
      long_name :
      latitude
      array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
    • longitude
      PandasIndex
      PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
             -174.375, -173.625, -172.875,
             ...
              172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
              178.125,  178.875,  179.625],
            dtype='float32', name='longitude', length=480))
    • latitude
      PandasIndex
      PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
              83.25,
             ...
             -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
              -90.0],
            dtype='float32', name='latitude', length=241))
In [10]:
t2c_tavg_max = ds.t2m.mean(dim='time').max()- 273.15
t2c_tavg_max
Out[10]:
<xarray.DataArray 't2m' ()>
array(33.40032349)
xarray.DataArray
't2m'
  • 33.4
    array(33.40032349)
      In [11]:
      ax = plt.axes(projection=ccrs.Robinson())
      t2c_mrange.plot.imshow(ax=ax, transform=ccrs.PlateCarree(),cbar_kwargs={'label': '°C'})
      ax.coastlines(); ax.gridlines()
      ax.set_title(r'$\overline{T_{M}}_{max}$ - $\overline{T_{M}}_{min}$, ERA5 1979-2018');
      
      No description has been provided for this image

      Questions¶

      1. Look at the zonal temperature anomaly map.

      • Explain why northern Europe and the North Atlantic region is significantly warmer than the same latitudes in North America or Russia.

      Answer: Due to the North Atlantic Drift originating the Gulf Stream, warm water ist transported into the North-East Atlantic causing milder temperatures of the adjacent land masses (Lecture 1, p. 25).

      • Explain why the Northern Pacific Ocean does not have a similar pattern.

      Answer: The Gulf Stream is a unique current in the Atlantic ocean. In the Pacific, ocean currents are different, warm currents do not reach as much north to have similar effects on temperatures avriations on land masses (Lecture 1, p. 25).

      2. Look at the average monthly temperature range map.

      • Explain why the temperature range is smaller in the tropics than at higher latitudes

      Answer: In the tropics, the daily insolation is quite uniform over the year. Therefore, seasonal temperature variations are not profound and daily temperature variations are more significant. In the highler latitudes the exposure to sunlight varies over the year leading to strong seasonal temperature variations (Schönewiese, 2013, p. 113 f.).

      • Explain why the temperature range is smaller over oceans than over land

      Answer: Oceans have a much higher heat capacity than land masses and heat up much slower. Therefore, over oceans temperatures are more moderate than over land masses (Lecture 3, p. 11).

      • Where is the temperature range largest? Explain why.

      Answer: The largest temperature ranges appear in the high latitudes as the sun insolation varies strongly with summer and winter season. Also ice covered areas have higher ranges due to the high albedo of snow and ice (Schönewiese, 2013, p. 113f.).

      Part 2 - Precipitation climatology¶

      Open the precipitation file and explore it. The units of monthly precipitation are wrongly labeled (unfortunately). They should read: m per day.

      In [12]:
      ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_tp.nc')
      ds
      
      Out[12]:
      <xarray.Dataset>
      Dimensions:    (longitude: 480, latitude: 241, time: 480)
      Coordinates:
        * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
        * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
        * time       (time) datetime64[ns] 1979-01-01 1979-02-01 ... 2018-12-01
      Data variables:
          tp         (time, latitude, longitude) float32 ...
      Attributes:
          Conventions:  CF-1.6
          history:      2019-11-18 09:30:18 GMT by grib_to_netcdf-2.14.0: /opt/ecmw...
      xarray.Dataset
        • longitude: 480
        • latitude: 241
        • time: 480
        • longitude
          (longitude)
          float32
          -179.6 -178.9 ... 178.9 179.6
          units :
          degrees_east
          long_name :
          longitude
          array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
                dtype=float32)
        • latitude
          (latitude)
          float32
          90.0 89.25 88.5 ... -89.25 -90.0
          units :
          degrees_north
          long_name :
          latitude
          array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
        • time
          (time)
          datetime64[ns]
          1979-01-01 ... 2018-12-01
          long_name :
          time
          array(['1979-01-01T00:00:00.000000000', '1979-02-01T00:00:00.000000000',
                 '1979-03-01T00:00:00.000000000', ..., '2018-10-01T00:00:00.000000000',
                 '2018-11-01T00:00:00.000000000', '2018-12-01T00:00:00.000000000'],
                dtype='datetime64[ns]')
        • tp
          (time, latitude, longitude)
          float32
          ...
          units :
          m
          long_name :
          Total precipitation
          [55526400 values with dtype=float32]
        • longitude
          PandasIndex
          PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
                 -174.375, -173.625, -172.875,
                 ...
                  172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
                  178.125,  178.875,  179.625],
                dtype='float32', name='longitude', length=480))
        • latitude
          PandasIndex
          PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
                  83.25,
                 ...
                 -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
                  -90.0],
                dtype='float32', name='latitude', length=241))
        • time
          PandasIndex
          PandasIndex(DatetimeIndex(['1979-01-01', '1979-02-01', '1979-03-01', '1979-04-01',
                         '1979-05-01', '1979-06-01', '1979-07-01', '1979-08-01',
                         '1979-09-01', '1979-10-01',
                         ...
                         '2018-03-01', '2018-04-01', '2018-05-01', '2018-06-01',
                         '2018-07-01', '2018-08-01', '2018-09-01', '2018-10-01',
                         '2018-11-01', '2018-12-01'],
                        dtype='datetime64[ns]', name='time', length=480, freq=None))
      • Conventions :
        CF-1.6
        history :
        2019-11-18 09:30:18 GMT by grib_to_netcdf-2.14.0: /opt/ecmwf/eccodes/bin/grib_to_netcdf -o /cache/data6/adaptor.mars.internal-1574069158.6891544-6829-11-3cc28eae-3777-426d-a5fe-bd3c8ecce585.nc /cache/tmp/3cc28eae-3777-426d-a5fe-bd3c8ecce585-adaptor.mars.internal-1574069158.6900353-6829-4-tmp.grib

      Using .groupby(), compute the average daily precipitation for each month of the year (I expect a variable of dimensions (month: 12, latitude: 241, longitude: 480)). Convert the units to mm per day. Plot a map of average daily precipitation in January and in August with the levels [0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40] and the colormap `YlGnBu'

      Average daily precipitation for each month of the year¶

      In [13]:
      precip_davg_mpd=ds.tp.groupby('time.month').mean()
      precip_davg_mmpd = precip_davg_mpd * 1000
      precip_davg_mmpd
      
      Out[13]:
      <xarray.DataArray 'tp' (month: 12, latitude: 241, longitude: 480)>
      array([[[0.46101883, 0.46101883, 0.46101883, ..., 0.46101883,
               0.46101883, 0.46101883],
              [0.43445352, 0.4340633 , 0.43381488, ..., 0.4358723 ,
               0.43530464, 0.43484366],
              [0.42448688, 0.4241676 , 0.4239195 , ..., 0.4255508 ,
               0.4248062 , 0.42477092],
              ...,
              [0.10928027, 0.11186972, 0.11350112, ..., 0.10282509,
               0.10431492, 0.10683304],
              [0.14439403, 0.14549373, 0.14634468, ..., 0.14180495,
               0.14290428, 0.14403927],
              [0.11853771, 0.11853771, 0.11853771, ..., 0.11853771,
               0.11853771, 0.11853771]],
      
             [[0.39777923, 0.39777923, 0.39777923, ..., 0.39777923,
               0.39777923, 0.39777923],
              [0.38057715, 0.38022232, 0.379832  , ..., 0.381393  ,
               0.38100296, 0.38057715],
              [0.37330613, 0.37319958, 0.37312898, ..., 0.37390924,
               0.37351903, 0.37355432],
      ...
              [0.1421948 , 0.14528054, 0.14765728, ..., 0.13499466,
               0.13666181, 0.13949908],
              [0.19483007, 0.19607171, 0.19720598, ..., 0.19117697,
               0.19280845, 0.1942982 ],
              [0.15581465, 0.15581465, 0.15581465, ..., 0.15581465,
               0.15581465, 0.15581465]],
      
             [[0.48095238, 0.48095238, 0.48095238, ..., 0.48095238,
               0.48095238, 0.48095238],
              [0.46825466, 0.46811283, 0.46797088, ..., 0.46868047,
               0.468574  , 0.4683611 ],
              [0.46048725, 0.46091294, 0.46116143, ..., 0.45928127,
               0.4594232 , 0.4598489 ],
              ...,
              [0.095696  , 0.09814343, 0.10037785, ..., 0.08899234,
               0.09065913, 0.09324849],
              [0.12272279, 0.12350287, 0.12428332, ..., 0.12038155,
               0.12141028, 0.12233267],
              [0.09392229, 0.09392229, 0.09392229, ..., 0.09392229,
               0.09392229, 0.09392229]]], dtype=float32)
      Coordinates:
        * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
        * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
        * month      (month) int64 1 2 3 4 5 6 7 8 9 10 11 12
      xarray.DataArray
      'tp'
      • month: 12
      • latitude: 241
      • longitude: 480
      • 0.461 0.461 0.461 0.461 0.461 ... 0.09392 0.09392 0.09392 0.09392
        array([[[0.46101883, 0.46101883, 0.46101883, ..., 0.46101883,
                 0.46101883, 0.46101883],
                [0.43445352, 0.4340633 , 0.43381488, ..., 0.4358723 ,
                 0.43530464, 0.43484366],
                [0.42448688, 0.4241676 , 0.4239195 , ..., 0.4255508 ,
                 0.4248062 , 0.42477092],
                ...,
                [0.10928027, 0.11186972, 0.11350112, ..., 0.10282509,
                 0.10431492, 0.10683304],
                [0.14439403, 0.14549373, 0.14634468, ..., 0.14180495,
                 0.14290428, 0.14403927],
                [0.11853771, 0.11853771, 0.11853771, ..., 0.11853771,
                 0.11853771, 0.11853771]],
        
               [[0.39777923, 0.39777923, 0.39777923, ..., 0.39777923,
                 0.39777923, 0.39777923],
                [0.38057715, 0.38022232, 0.379832  , ..., 0.381393  ,
                 0.38100296, 0.38057715],
                [0.37330613, 0.37319958, 0.37312898, ..., 0.37390924,
                 0.37351903, 0.37355432],
        ...
                [0.1421948 , 0.14528054, 0.14765728, ..., 0.13499466,
                 0.13666181, 0.13949908],
                [0.19483007, 0.19607171, 0.19720598, ..., 0.19117697,
                 0.19280845, 0.1942982 ],
                [0.15581465, 0.15581465, 0.15581465, ..., 0.15581465,
                 0.15581465, 0.15581465]],
        
               [[0.48095238, 0.48095238, 0.48095238, ..., 0.48095238,
                 0.48095238, 0.48095238],
                [0.46825466, 0.46811283, 0.46797088, ..., 0.46868047,
                 0.468574  , 0.4683611 ],
                [0.46048725, 0.46091294, 0.46116143, ..., 0.45928127,
                 0.4594232 , 0.4598489 ],
                ...,
                [0.095696  , 0.09814343, 0.10037785, ..., 0.08899234,
                 0.09065913, 0.09324849],
                [0.12272279, 0.12350287, 0.12428332, ..., 0.12038155,
                 0.12141028, 0.12233267],
                [0.09392229, 0.09392229, 0.09392229, ..., 0.09392229,
                 0.09392229, 0.09392229]]], dtype=float32)
        • longitude
          (longitude)
          float32
          -179.6 -178.9 ... 178.9 179.6
          units :
          degrees_east
          long_name :
          longitude
          array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
                dtype=float32)
        • latitude
          (latitude)
          float32
          90.0 89.25 88.5 ... -89.25 -90.0
          units :
          degrees_north
          long_name :
          latitude
          array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
        • month
          (month)
          int64
          1 2 3 4 5 6 7 8 9 10 11 12
          array([ 1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12], dtype=int64)
        • longitude
          PandasIndex
          PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
                 -174.375, -173.625, -172.875,
                 ...
                  172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
                  178.125,  178.875,  179.625],
                dtype='float32', name='longitude', length=480))
        • latitude
          PandasIndex
          PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
                  83.25,
                 ...
                 -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
                  -90.0],
                dtype='float32', name='latitude', length=241))
        • month
          PandasIndex
          PandasIndex(Index([1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12], dtype='int64', name='month'))
      In [14]:
      precip_davg_mmpd_jan= precip_davg_mmpd[0]
      precip_davg_mmpd_jan
      
      Out[14]:
      <xarray.DataArray 'tp' (latitude: 241, longitude: 480)>
      array([[0.46101883, 0.46101883, 0.46101883, ..., 0.46101883, 0.46101883,
              0.46101883],
             [0.43445352, 0.4340633 , 0.43381488, ..., 0.4358723 , 0.43530464,
              0.43484366],
             [0.42448688, 0.4241676 , 0.4239195 , ..., 0.4255508 , 0.4248062 ,
              0.42477092],
             ...,
             [0.10928027, 0.11186972, 0.11350112, ..., 0.10282509, 0.10431492,
              0.10683304],
             [0.14439403, 0.14549373, 0.14634468, ..., 0.14180495, 0.14290428,
              0.14403927],
             [0.11853771, 0.11853771, 0.11853771, ..., 0.11853771, 0.11853771,
              0.11853771]], dtype=float32)
      Coordinates:
        * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
        * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
          month      int64 1
      xarray.DataArray
      'tp'
      • latitude: 241
      • longitude: 480
      • 0.461 0.461 0.461 0.461 0.461 ... 0.1185 0.1185 0.1185 0.1185 0.1185
        array([[0.46101883, 0.46101883, 0.46101883, ..., 0.46101883, 0.46101883,
                0.46101883],
               [0.43445352, 0.4340633 , 0.43381488, ..., 0.4358723 , 0.43530464,
                0.43484366],
               [0.42448688, 0.4241676 , 0.4239195 , ..., 0.4255508 , 0.4248062 ,
                0.42477092],
               ...,
               [0.10928027, 0.11186972, 0.11350112, ..., 0.10282509, 0.10431492,
                0.10683304],
               [0.14439403, 0.14549373, 0.14634468, ..., 0.14180495, 0.14290428,
                0.14403927],
               [0.11853771, 0.11853771, 0.11853771, ..., 0.11853771, 0.11853771,
                0.11853771]], dtype=float32)
        • longitude
          (longitude)
          float32
          -179.6 -178.9 ... 178.9 179.6
          units :
          degrees_east
          long_name :
          longitude
          array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
                dtype=float32)
        • latitude
          (latitude)
          float32
          90.0 89.25 88.5 ... -89.25 -90.0
          units :
          degrees_north
          long_name :
          latitude
          array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
        • month
          ()
          int64
          1
          array(1, dtype=int64)
        • longitude
          PandasIndex
          PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
                 -174.375, -173.625, -172.875,
                 ...
                  172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
                  178.125,  178.875,  179.625],
                dtype='float32', name='longitude', length=480))
        • latitude
          PandasIndex
          PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
                  83.25,
                 ...
                 -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
                  -90.0],
                dtype='float32', name='latitude', length=241))
      In [15]:
      ax = plt.axes(projection=ccrs.Robinson())
      precip_davg_mmpd_jan.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), levels=[0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40], cmap='YlGnBu', cbar_kwargs={'label': 'mm/day'})
      ax.coastlines(); ax.gridlines()
      plt.title('Average daily precipitation in January, ERA5 1979-2018');
      
      No description has been provided for this image
      In [16]:
      precip_davg_mmpd_aug= precip_davg_mmpd[7]
      precip_davg_mmpd_aug
      
      Out[16]:
      <xarray.DataArray 'tp' (latitude: 241, longitude: 480)>
      array([[1.238129  , 1.238129  , 1.238129  , ..., 1.238129  , 1.238129  ,
              1.238129  ],
             [1.2375971 , 1.2374201 , 1.2371716 , ..., 1.2365686 , 1.2371713 ,
              1.2374197 ],
             [1.2364265 , 1.236604  , 1.2373135 , ..., 1.2347952 , 1.2357881 ,
              1.2363559 ],
             ...,
             [0.14737323, 0.14957199, 0.1517714 , ..., 0.14173388, 0.14336519,
              0.14528054],
             [0.19592941, 0.19692248, 0.19777371, ..., 0.19334015, 0.19419147,
              0.19536187],
             [0.18330272, 0.18330272, 0.18330272, ..., 0.18330272, 0.18330272,
              0.18330272]], dtype=float32)
      Coordinates:
        * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
        * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
          month      int64 8
      xarray.DataArray
      'tp'
      • latitude: 241
      • longitude: 480
      • 1.238 1.238 1.238 1.238 1.238 ... 0.1833 0.1833 0.1833 0.1833 0.1833
        array([[1.238129  , 1.238129  , 1.238129  , ..., 1.238129  , 1.238129  ,
                1.238129  ],
               [1.2375971 , 1.2374201 , 1.2371716 , ..., 1.2365686 , 1.2371713 ,
                1.2374197 ],
               [1.2364265 , 1.236604  , 1.2373135 , ..., 1.2347952 , 1.2357881 ,
                1.2363559 ],
               ...,
               [0.14737323, 0.14957199, 0.1517714 , ..., 0.14173388, 0.14336519,
                0.14528054],
               [0.19592941, 0.19692248, 0.19777371, ..., 0.19334015, 0.19419147,
                0.19536187],
               [0.18330272, 0.18330272, 0.18330272, ..., 0.18330272, 0.18330272,
                0.18330272]], dtype=float32)
        • longitude
          (longitude)
          float32
          -179.6 -178.9 ... 178.9 179.6
          units :
          degrees_east
          long_name :
          longitude
          array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
                dtype=float32)
        • latitude
          (latitude)
          float32
          90.0 89.25 88.5 ... -89.25 -90.0
          units :
          degrees_north
          long_name :
          latitude
          array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
        • month
          ()
          int64
          8
          array(8, dtype=int64)
        • longitude
          PandasIndex
          PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
                 -174.375, -173.625, -172.875,
                 ...
                  172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
                  178.125,  178.875,  179.625],
                dtype='float32', name='longitude', length=480))
        • latitude
          PandasIndex
          PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
                  83.25,
                 ...
                 -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
                  -90.0],
                dtype='float32', name='latitude', length=241))
      In [17]:
      ax = plt.axes(projection=ccrs.Robinson())
      precip_davg_mmpd_aug.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), levels=[0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40], cmap='YlGnBu', cbar_kwargs={'label': 'mm/day'})
      ax.coastlines(); ax.gridlines()
      plt.title('Average daily precipitation in August, ERA5 1979-2018');
      
      No description has been provided for this image

      Questions¶

      1. Describe the location of the ITCZ in January and February. Without going into the details, explain (in one or two sentences)

      Answer: The ITCZ in January and February is around the equator with as shift torwards southern hemisphere due to warmer temperatures and summer season in the southern hemisphere. (Lecture 1, p. 13)

      2. Describe the precipitation seasonality in West Africa and in India. Name the phenomenon at play.

      Answer: In India and West Africa have both seasons of heavy precipitation caused by the seasonal shifts of windblow due to the ITCZ-shifting, named Monsoon. Both in West Africa and India, the Monsoon season is present in June to Septemper contributing to a major share of the region's overall rainfall. (India Meteorologicsl Centre 2023, Raj et al., 2019, p. 6444)

      Part 3: sea-level pressure and surface winds¶

      Open the file containing the surface winds (u10 and v10) and sea-level pressure (msl).

      Compute $\left[ \overline{SLP} \right]$ (the temporal and zonal average of sea-level pressure). Convert it to hPa, and plot it (line plot). With the help of plt.axhline, add the standard atmosphere pressure line to the plot to emphasize high and low pressure regions. Repeat with $\left[ \overline{u_{10}} \right]$ and $\left[ \overline{v_{10}} \right]$ (in m s$^{-1}$) and add the 0 horizontal line to the plot (to detect surface westerlies from easterlies for example).

      In [18]:
      ds = xr.open_dataset(r'../data/ERA5_LowRes_Monthly_uvslp.nc')
      ds
      
      Out[18]:
      <xarray.Dataset>
      Dimensions:    (longitude: 480, latitude: 241, time: 480)
      Coordinates:
        * longitude  (longitude) float32 -179.6 -178.9 -178.1 ... 178.1 178.9 179.6
        * latitude   (latitude) float32 90.0 89.25 88.5 87.75 ... -88.5 -89.25 -90.0
        * time       (time) datetime64[ns] 1979-01-01 1979-02-01 ... 2018-12-01
      Data variables:
          u10        (time, latitude, longitude) float32 ...
          v10        (time, latitude, longitude) float32 ...
          msl        (time, latitude, longitude) float32 ...
      Attributes:
          Conventions:  CF-1.6
          history:      2019-11-24 19:42:05 GMT by grib_to_netcdf-2.14.0: /opt/ecmw...
      xarray.Dataset
        • longitude: 480
        • latitude: 241
        • time: 480
        • longitude
          (longitude)
          float32
          -179.6 -178.9 ... 178.9 179.6
          units :
          degrees_east
          long_name :
          longitude
          array([-179.625, -178.875, -178.125, ...,  178.125,  178.875,  179.625],
                dtype=float32)
        • latitude
          (latitude)
          float32
          90.0 89.25 88.5 ... -89.25 -90.0
          units :
          degrees_north
          long_name :
          latitude
          array([ 90.  ,  89.25,  88.5 , ..., -88.5 , -89.25, -90.  ], dtype=float32)
        • time
          (time)
          datetime64[ns]
          1979-01-01 ... 2018-12-01
          long_name :
          time
          array(['1979-01-01T00:00:00.000000000', '1979-02-01T00:00:00.000000000',
                 '1979-03-01T00:00:00.000000000', ..., '2018-10-01T00:00:00.000000000',
                 '2018-11-01T00:00:00.000000000', '2018-12-01T00:00:00.000000000'],
                dtype='datetime64[ns]')
        • u10
          (time, latitude, longitude)
          float32
          ...
          units :
          m s**-1
          long_name :
          10 metre U wind component
          [55526400 values with dtype=float32]
        • v10
          (time, latitude, longitude)
          float32
          ...
          units :
          m s**-1
          long_name :
          10 metre V wind component
          [55526400 values with dtype=float32]
        • msl
          (time, latitude, longitude)
          float32
          ...
          units :
          Pa
          long_name :
          Mean sea level pressure
          standard_name :
          air_pressure_at_mean_sea_level
          [55526400 values with dtype=float32]
        • longitude
          PandasIndex
          PandasIndex(Index([-179.625, -178.875, -178.125, -177.375, -176.625, -175.875, -175.125,
                 -174.375, -173.625, -172.875,
                 ...
                  172.875,  173.625,  174.375,  175.125,  175.875,  176.625,  177.375,
                  178.125,  178.875,  179.625],
                dtype='float32', name='longitude', length=480))
        • latitude
          PandasIndex
          PandasIndex(Index([  90.0,  89.25,   88.5,  87.75,   87.0,  86.25,   85.5,  84.75,   84.0,
                  83.25,
                 ...
                 -83.25,  -84.0, -84.75,  -85.5, -86.25,  -87.0, -87.75,  -88.5, -89.25,
                  -90.0],
                dtype='float32', name='latitude', length=241))
        • time
          PandasIndex
          PandasIndex(DatetimeIndex(['1979-01-01', '1979-02-01', '1979-03-01', '1979-04-01',
                         '1979-05-01', '1979-06-01', '1979-07-01', '1979-08-01',
                         '1979-09-01', '1979-10-01',
                         ...
                         '2018-03-01', '2018-04-01', '2018-05-01', '2018-06-01',
                         '2018-07-01', '2018-08-01', '2018-09-01', '2018-10-01',
                         '2018-11-01', '2018-12-01'],
                        dtype='datetime64[ns]', name='time', length=480, freq=None))
      • Conventions :
        CF-1.6
        history :
        2019-11-24 19:42:05 GMT by grib_to_netcdf-2.14.0: /opt/ecmwf/eccodes/bin/grib_to_netcdf -o /cache/data6/adaptor.mars.internal-1574624177.1107812-30733-5-d94977a6-abdd-4375-98f2-61cd60af6f37.nc /cache/tmp/d94977a6-abdd-4375-98f2-61cd60af6f37-adaptor.mars.internal-1574624177.1114278-30733-2-tmp.grib
      In [19]:
      msl_avg = ds.msl.mean(dim='time') #mean over time
      msl_zonal = msl_avg.mean(dim='longitude')*10**(-2) #mean over lon and coversion into hPa
      
      msl_zonal.plot(label = 'zonal and temporal average sea-level pressure');
      plt.axhline(1013.25,color ='r',label='standard atmosphere pressure');
      plt.legend();
      plt.ylabel('Pressure in hPa');
      plt.xlabel('Latitude in degrees north');
      plt.title('zonal sea level pressure vs standard atmosphere pressure');
      
      No description has been provided for this image
      In [20]:
      u10_avg = ds.u10.mean(dim='time') #mean over time
      u10_zonal = u10_avg.mean(dim='longitude') #mean over lon
      
      u10_zonal.plot(label = 'zonal and temporal average 10m U wind component');
      plt.axhline(0,color ='r',label='zero line');
      plt.legend();
      plt.ylabel('Windspeed in m/s');
      plt.xlabel('Latitude in degrees north');
      plt.title('zonal 10m U wind component vs zero line');
      
      No description has been provided for this image
      In [21]:
      v10_avg = ds.v10.mean(dim='time') #mean over time
      v10_zonal = v10_avg.mean(dim='longitude') #mean over lon
      
      v10_zonal.plot(label = 'zonal and temporal average 10m V wind component');
      plt.axhline(0,color ='r',label='zero line');
      plt.legend();
      plt.ylabel('Windspeed in m/s');
      plt.xlabel('Latitude in degrees north');
      plt.title('zonal 10m V wind component vs zero line');
      
      No description has been provided for this image

      Questions: 1. Based on your knowledge about the general circulation of the atmosphere, explain the latitude location of the climatological high and low pressure systems of Earth?

      Answer:

      • Equatorial low pressure belt also known as ICTZ around the equator:
        • Explanation: Receives highest solar energy, which heats up the air temperature, leading to a decrease of pressure (NOAA 2023a)
      • Subtropical high pressure belt at 30° N/S latitude for both hemispheres
        • Explanation: Heated air coming from equator has cooled down and is sinking down (NOAA 2023a)
      • Polar belt of low pressure belt at 60° N/S latitude for both hemispheres

      2. Similarly, explain the direction and strength of the zonal and meridional winds on earth (tip: the sea-level pressure plot helps)

      Answer:

      • Meridional winds (v wind) circulate from North to South or South to North, parallel to longitudes (Schönewiese, 2013, 163).
        • Explanation: At -50deg we have a large u-wind, as there is only sea at this latitude, which is why the wind is mainly dominated by the Coriolis force and the wind is not deflected. At the equator, we have the trade winds that go from west to east. The wind comes from the high-pressure area near the equator and flows towards the equator into the low-pressure area, which is directed to the west by the Coriolis force. Closer to the poles are the westerlies, which are located at the Ferrel cell, and even closer to the poles we have easterlies again at the Polar cell (Lecture 1, p. 11).
      • Zonal winds (u wind) circulate from West to East or West to East, parallel to latitudes (Schönewiese, 2013, 163)
        • Explanation: North to south, the zeros are always the end or beginning of a cell. From about 0 to 30 degrees is the Hadley cell, from 30 to 60 degrees the Ferrel and then Polar cell. The winds always flow in the direction of the cells, e.g. between 0 and 30 degrees everything flows south to the ITCZ where the Hadley cell "ends" (Lecture 1, p. 11).
      • Meridional winds generally have a weaker velocity than zonal winds. Strongest zonal winds can reach up to 30 m/s near 30◦ latitude in the winter hemisphere at 200 mbar. Mean merdional winds (northwards) habe a velocity < 1 m/s at 200 mbar. (Marshall un Plumb, 2008, p. 73 f.)

      Part 4: temperature change and CO$_2$ concentrations¶

      Download the global average CO$_2$ concentration timeseries data in the CSV format (source: NOAA). Here, let me help your read them using pandas:

      In [22]:
      #df = pd.read_csv('../data/co2_mm_gl.csv', skiprows=55, parse_dates={'date' : [0, 1]}, index_col='date')
      df = pd.read_csv('../data/co2_mm_gl.csv', skiprows=38)
      #changed skiprows from 55 to 38 and removed the part that fused the year and month together
      

      Prepare three plots:

      • plot the monthly global CO$_2$ concentration as a function of time.
      • plot the annual average timeseries of global CO$_2$ concentration as a function of time.
      • plot the annual average timeseries of global CO$_2$ concentration and of global 2m temperature from ERA5 on the same plot (using a secondary y axis for temperature).
      In [23]:
      #will use average
      months = df.groupby('month'); #grouping all months together
      months.average.mean() #meaning the average co2
      months.average_unc.mean(); #meaning the uncertainty
      
      In [24]:
      months.average.mean().plot(yerr = months.average_unc.mean(),label='average CO2 levels')
      plt.ylabel('CO2 concentration in ppm');
      plt.xlabel('Month');
      plt.legend();
      plt.title('annual CO2 cycle');
      
      No description has been provided for this image
      In [25]:
      years = df.groupby('year')
      years.average.mean().plot(label='average CO2 levels')
      plt.ylabel('CO2 concentration in ppm');
      plt.xlabel('Year');
      plt.legend();
      plt.title('CO2 levels over the years');
      
      No description has been provided for this image
      In [26]:
      ds = xr.open_dataset('../code/data/ERA5_LowRes_Monthly_t2m.nc')
      years = df.groupby('year')
      # Meridional weights
      weight = np.cos(np.deg2rad(ds.latitude))
      weight = weight / weight.sum()
      
      # Meridionally weighted zonal mean
      zonal_mean = ds.t2m.mean(dim='longitude') - 273.15  # convert into Celsius
      weighted_zonal_mean = zonal_mean * weight
      weighted_mean = weighted_zonal_mean.sum(dim='latitude')
      
      jahre = np.linspace(1979, 2018, num=40) #little bit of trickery, it wouldnt plot the years properly otherwise
      
      fig, ax1 = plt.subplots()#two plots in one
      
      ax1.set_xlabel('year')
      ax1.set_ylabel('2m temperature in C',color = 'r')
      ax1.plot(jahre,weighted_mean.resample(time = 'AS').mean(),color = 'r', label = '2m temperature')
      ax1.tick_params(axis='y',labelcolor = 'r')
      
      ax2 = ax1.twinx()
      ax2.set_ylabel('CO2 concentration in ppm',color = 'b')
      ax2.plot(years.average.mean(),label='average CO2 levels',color = 'b')
      ax2.tick_params(axis='y',labelcolor = 'b')
      
      ax1.set_title('CO2 concentration vs temperature')
      fig.tight_layout()
      plt.show()
      
      No description has been provided for this image
      In [27]:
      #calculating co2 increase 1980-85
      n = 1980
      diff = 0
      sum = 0
      while n < 1985:
          diff = years.mean()["average"][n+1] - years.mean()["average"][n] 
          sum = sum + diff
          n = n+1
      
      avg80_85 = sum/5
      print(avg80_85)
      
      #2016-21
      
      n = 2016
      diff = 0
      sum = 0
      while n < 2021:
          diff = years.mean()["average"][n+1] - years.mean()["average"][n] 
          sum = sum + diff
          n = n+1
      
      avg16_21 = sum/5
      print(avg16_21)
      
      1.325166666666655
      2.327333333333331
      

      Questions:

      1. Describe and explain the annual cycle of CO$_2$ concentrations

      Answer:

      • General decreasing CO$_2$ concentrations during summer season of both hemispheres.
      • Northern hemisphere has genrally significant higher CO$_2$ concentrations and stronger variations of concentration with summer and winter season than southern hemisphere.
      • Main reason for seasonal varaition and differences between hemispheres is due to vegetation's capcity for binding CO$_2$. Generally, in summer and spring season plants are able to take CO$_2$ out of the atmosphere with photosynthesis. It should be considered: there is a daly of 3 months within this process as the feedback needs time to develp. This effect is stronger in northern hemisphere due to more land masses and thus more variation in vegetation over the year. (Copernicus 2019, NASA 2019)
      • Additional reason for seasonal differences: heating emissions during colder winter months. (Geography Lecture on Human-Environment-Relationship)
      • Reason for generally higher CO$_2$ concentrations in northern hemisphere: Majority of human population is living in northern hemisphere and the northern hemisphere has more industrial activity. (Geography Lecture on Human-Environment-Relationship)

      3. What was the CO$_2$ concentration in the atmosphere in the pre-industrial era? Compute the annual increase in CO$_2$ concentration (unit: ppm per year) between 1980 and 1985 and between 2016 and 2021.

      Answer:

      • Preindustrial level: 280 ppm or less (NOAA, 2022)
      • 1985-1990:1,325 ppm per year
      • 2016-2021: 2,327 ppm per year

      4. Describe the relationship between global temperatures and CO$_2$ concentrations. Beside CO$_2$, name three processes that can influence temperature variability and change at the global scale.

      Answer:

      • Temperatures are proportional to CO$_2$ concentrations
      • Processes that can influence temperature variability and change at the global scale
        • Milancovic cycles: eccentricity, obliquity, precession (Lecture 4 p. 8)
        • Internal osciallations and cycles as e.g. the El Niño–Southern Oscillation (ENSO)(Lecture 4 p. 14)
        • Variations in solar activity (Lecture 4 p. 9)

      Part 5: variability and ENSO (open research question)¶

      As of November 2023, the world is currently experiencing El Niño conditions, with projections indicating its persistence through the upcoming spring (source). To understand the implications and compare with La Niña, we will utilize our available data.

      Using your learned skills, you should create global anomalie maps of sea-surface temperature, precipitation, and air temperature, comparing one El Niño with one La Niña year. Describe the anomaly patterns you are seeing in your plots (e.g. where do we see an increase/decrease in precipitation).

      We suggest to look for literature or a google search on strong ENSO events in the past 40 years, and select one good example for a positive and a negative phase. With citation or links, explain why you picked these years as examples.

      Global anomalie map of sea-surface temperature¶

      Choice of year:

      • Genaral approach for choosing a good example for a negative and positive phase: As La Niña events are connected to the preceeding El Niño event (Geng et al., 2023, p. 774), two consecutive phases have been chosen.
      • Picking a strong ENSO events, both the amplitude of the Oceanic Niño Index (ONI) of consecutive El Niño and La Niña phases, and the persistance of the La Niña phase have been considered. Because unlike El Niño events, La Niña events can last more than one year (Geng et al., 2023, p. 774).
      • The strongest El Niño events have been measured in 1997-1998 and 2015-2016. While the ONI in 2015-2016 peaked higher, the El Niño in 1997-1998 was followed by a colder and longer lasting La Niña with a rare "triple-dip" (NOAA, 2023b). Therefore, the El Niño in 1997-1998 has been chosen with consecutive La Niña in 1999-2001. El Niño in 1997-1998 has its highest mean anomaly in 1997 peaking in November 1997 with 2.40 (NOAA, 2023c). The 1998-2000 La Niña phase has its highest mean anomaly 1999 peaking January 2000 with -1.66. But the peak is not much higher the 1999 peak with -1.6 (NOAA, 2023c)
      • In the follwing the El Niño year 1997 and La Niña year 1999 have been chosen for the anomaly maps

      Choice of region:

      • Focus on Ausralia as it is concerned by both temperature and percipitaion variations due to ENSO (NOAA, 2023d)

      Global anomaly patterns:

      • Strongest anomalies by temperature and precipitation increase in Pacific region during El Niño
        • Percipitaion anomaly especially around Pacific equatorial latitude
        • Temperature anomaly espcially in east pacific around equator and higher latitudes of northern hemisphere (Alaska, East Russia)
      • Further significant temperature increases during El Niño in Latin America, Australia, Central Asia
      • Significant temperature decrease during El Niño in northern east coast of North America

      Anomaly Patterns Australia

      • Precipitation: Compared to La Niña , precipitation in El Niño is significantly higher
      • Temperature: During El Niño over coastal areas the temperature increases compared to la Nina, while within inner country temperature decreases
      • Over New Zealand temperature deacreases in El Niño
      In [28]:
      sst = xr.open_dataset(r'..\data\ERA5_LowRes_Monthly_sst.nc')
      sst_nino = sst.sst.sel(time='1997').mean(dim='time') 
      sst_nina = sst.sst.sel(time='1999').mean(dim='time') 
      
      sstdiff = sst_nino - sst_nina
      
      
      ax = plt.axes(projection=ccrs.Robinson())
      sstdiff.plot(ax=ax, transform=ccrs.PlateCarree(),cbar_kwargs={'label': '°C'})
      ax.coastlines(); ax.gridlines();
      
      ax.set_title('Average sea surface temperature difference between El Nino 1997 and La Nina 1999');
      
      No description has been provided for this image
      In [29]:
      t2m = xr.open_dataset(r'..\data\ERA5_LowRes_Monthly_t2m.nc')
      t2m_nino = t2m.t2m.sel(time='1997').mean(dim='time') 
      t2m_nina = t2m.t2m.sel(time='1999').mean(dim='time') 
      t2mdiff = t2m_nino - t2m_nina
      
      
      ax = plt.axes(projection=ccrs.Robinson())
      t2mdiff.plot(ax=ax, transform=ccrs.PlateCarree(),cbar_kwargs={'label': '°C'})
      ax.coastlines(); ax.gridlines();
      
      ax.set_title('Average 2 m temperature difference between El Nino 1997 and La Nina 1999');
      
      No description has been provided for this image
      In [30]:
      tp = xr.open_dataset(r'..\data\ERA5_LowRes_Monthly_tp.nc')
      
      tp_nino = tp.tp.sel(time='1997').mean(dim='time') 
      tp_nina = tp.tp.sel(time='1999').mean(dim='time') 
      tpdiff = (tp_nino - tp_nina)*1000
      
      ax = plt.axes(projection=ccrs.Robinson())
      tpdiff.plot.imshow(ax=ax, transform=ccrs.PlateCarree(),cbar_kwargs={'label': 'mm/day'},cmap='YlGnBu',levels= [-20, -15,-10,-5, 0,2.5, 5, 7,5, 10, 12.5, 15,17.5, 20])
      ax.coastlines(); ax.gridlines();
      
      ax.set_title('Average precipitation difference between El Nino 1997 and La Nina 1999');
      
      No description has been provided for this image
      In [31]:
      t2m_aus = t2mdiff.sel(longitude=slice(90, 180),latitude=slice(0,-50))
      ax = plt.axes(projection=ccrs.PlateCarree())
      t2m_aus.plot.imshow(ax=ax, transform=ccrs.PlateCarree(),cbar_kwargs={'label': '°C'})
      ax.coastlines();
      ax.set_title('Average 2 m temperature difference between El Nino 1997 and La Nina 1999');
      
      No description has been provided for this image
      In [32]:
      tp_aus = tpdiff.sel(longitude=slice(90, 180),latitude=slice(0,-50))
      ax = plt.axes(projection=ccrs.PlateCarree())
      tp_aus.plot.imshow(ax=ax, transform=ccrs.PlateCarree(),cbar_kwargs={'label': 'mm/day'},cmap='YlGnBu',levels = [-20,-10,-5,-3,-2,-1,-0.5,0,0.5,1,2,3,5,10,20]) 
      ax.coastlines();
      ax.set_title('Average precipitation difference between El Nino 1997 and La Nina 1999');
      
      No description has been provided for this image

      Literature¶

      Geng et al. (2023), Increased occurrences of consecutive La Niña events under global warming, Nature 619, 774–781, https://doi.org/10.1038/s41586-023-06236-9 Marshall, Plumb and Plumb, R. Alan (2008), Atmosphere, ocean, and climate dynamics : an introductory text

      NOAA (2022), https://www.noaa.gov/news-release/carbon-dioxide-now-more-than-50-higher-than-pre-industrial-levels

      NOAA (2023a), https://www.weather.gov/source/zhu/ZHU_Training_Page/winds/Wx_Terms/Flight_Environment.htm

      NOAA (2023b), https://globalocean.noaa.gov/recent-triple-dip-la-nina-upends-current-understanding-of-enso/

      NOAA (2023c), https://www.cpc.ncep.noaa.gov/data/indices/oni.ascii.txt

      NOAA (2023d), https://www.climate.gov/news-features/featured-images/global-impacts-el-niño-and-la-niña

      Copernicus (2019), https://atmosphere.copernicus.eu/carbon-dioxide-levels-are-rising-it-really-simple NASA (2019), https://airs.jpl.nasa.gov/resources/122/watching-earth-breathe-the-seasonal-vegetation-cycle-and-atmospheric-carbon-dioxide/

      India Meteorological Centre (2023), https://mausam.imd.gov.in/imd_latest/monsoonfaq.pdf

      Raj, J., Bangalath, H.K. & Stenchikov, G. West (2019), African Monsoon: current state and future projections in a high-resolution AGCM. Clim Dyn 52, 6441–6461, https://doi.org/10.1007/s00382-018-4522-7

      Schönwiese, C.-D. (2013), Klimatologie, 4th edition, Eugen Ulmer, Stuttgart