Group project: the Climate System¶

Felix Petrasch und Paul Kollatz

Instructions¶

Objectives

In this final project, you will apply the methods you learned over the past weeks to answer the questions below.

Deadline

Please submit your project via OLAT before Thursday January 12 at 00H (in the night from Wednesday to Thursday).

Formal requirements

You will work in groups of two. If we are an odd number of students, one group can have three participants. (Tip: I recommend that students who have not followed my programming class to team up with students who have).

Each group will submit one (executed) jupyter notebook containing the code, plots, and answers to the questions (text in the markdown format). Please also submit an HTML version of the notebook. Each group member must contribute to the notebook. The notebook should be self-contained and the answers must be well structured. The plots must be as understandable as possible (title, units, x and y axis labels, appropriate colors and levels…).

Please be concise in your answer. I expect a few sentences per answer at most - there is no need to write a new text book in this project! Use links and references to the literature or your class slides where appropriate.

Grading

I will give one grade per project, according to the following table (total 10 points):

  • correctness of the code and the plots: content, legends, colors, units, etc. (3 points)
  • quality of the answers: correctness, preciseness, appropriate use of links and references to literature or external resources (5 points)
  • originality and quality of the open research question (2 points)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# 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
#ignore warnings
import warnings
warnings.filterwarnings('ignore')

Part 1 - temperature climatology¶

Open the ERA5 temperature data:

1
ds_t = xr.open_dataset('../data/ERA5_LowRes_Monthly_t2m.nc')

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 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.

Questions:

  1. Look at the zonal temperature anomaly map.
    • Explain why norther Europe and the North Atlantic region is significantly warmer than the same latitudes in North America or Russia.
    • Explain why the Northern Pacific Ocean does not have a similar pattern.
  2. Look at the average monthly temperature range map.
    • Explain why the temperature range is smaller in the tropics than at higher latitudes
    • Explain why the temperature range is smaller over oceans than over land
    • Where is the temperature range largest? Explain why.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
##1
## Compute and plot the temporal mean temperature 𝑇⎯ for the entire period (unit °C)

#calculate the Average annual 2m air temperature
t2_tavg = ds_t.t2m.mean(dim='time') - 273.15

#plot the average annual 2m air temperature
ax = plt.axes(projection=ccrs.Robinson())
t2_tavg.plot(ax=ax, transform=ccrs.PlateCarree(), cmap='inferno', center=False, vmin=-40, vmax=20, levels=7, cbar_kwargs={'label': '°C'}) 
ax.set_title('Average annual 2m air temperature')
ax.coastlines(); ax.gridlines(); 
No description has been provided for this image
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
##2
#Compute and plot 𝑇∗⎯ (see lesson), the zonal anomaly map of average temperature.

# calculate the zonal average temperature
zonal_average = t2_tavg.mean(dim='longitude')

# calculate the zonal anomaly by subtracting the long-term mean
zonal_anomaly = t2_tavg - zonal_average

# plot the zonal anomaly
ax = plt.axes(projection=ccrs.Robinson())
zonal_anomaly.plot(ax=ax, transform=ccrs.PlateCarree(), cmap='coolwarm', center=0, vmin=-30, vmax=30,cbar_kwargs={'label': '°C'}) 
ax.coastlines(); ax.gridlines()
plt.title('Zonal Temperature Anomaly')
Text(0.5, 1.0, 'Zonal Temperature Anomaly')
No description has been provided for this image
  • Explain why norther Europe and the North Atlantic region is significantly warmer than the same latitudes in North America or Russia.

    • The Gulf Stream is a warm ocean current that flows from the Gulf of Mexico towards Europe, which helps to keep the North Atlantic region and northern Europe warmer than North America or Russia by bringing warm water from the tropics to the North Atlantic. The North Atlantic Oscillation is a weather pattern that affects the temperature and precipitation in the North Atlantic region and when it is in its positive phase, it brings milder and wetter weather which helps to keep the temperatures warmer (04_ClimateFluctuationsDrivers slide 19). Northern Europe and the North Atlantic region have a relatively flat and low-lying topography which allows for the easy flow of warm air from the south, while North America and Russia have much more rugged and mountainous topography which can disrupt the flow of warm air and cause colder temperatures. Additionally, natural barriers such as the Scandinavian Mountains, the Atlantic Ocean, and the British Isles block cold Arctic air from reaching Europe, keeping the region warmer.
  • Explain why the Northern Pacific Ocean does not have a similar pattern.

    • The Northern Pacific Ocean has different weather patterns than the North Atlantic region due to the presence of the Aleutian Low, a low-pressure system that brings cool and wet weather to the Pacific Northwest coast of North America. The topography of North America, being more rugged and mountainous, also disrupts the flow of warm air and causes colder temperatures in the Pacific Northwest.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
##3
##Compute the monthly average temperature for each month 𝑇𝑀⎯(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. 𝑇𝑀⎯𝑚𝑎𝑥 - 𝑇𝑀-𝑚𝑖𝑛 on a map.

# group temperature data by month
monthly_temperature = ds_t.t2m.groupby('time.month').mean(dim='time')

# calculate the monthly temperature range
temperature_range = monthly_temperature.max(dim='month') - monthly_temperature.min(dim='month')

# plot the temperature range
ax = plt.axes(projection=ccrs.Robinson())
temperature_range.plot(ax=ax, transform=ccrs.PlateCarree(), cmap='plasma', center=False, vmin=0, vmax=55, levels=12, cbar_kwargs={'label': '°C'}) 
ax.coastlines();ax.gridlines()
plt.title('Monthly Temperature Range')
plt.show()
No description has been provided for this image
  • Explain why the temperature range is smaller in the tropics than at higher latitudes

    • The tropics have a smaller temperature range than higher latitudes due to factors such as the distribution of heat by the Earth's atmosphere and oceans, the intensity of solar radiation, and atmospheric circulation patterns. In the tropics, the sun's rays are more directly overhead, causing the surface to heat up more quickly and be more effectively cooled by the warm, moist tropical air and the ocean. This heat stored in the ocean also helps maintain a stable temperature throughout the year. In contrast, higher latitudes have less direct sunlight, slower surface heating, less effective cooling, and more variable atmospheric circulation patterns, leading to greater seasonal temperature variation.
  • Explain why the temperature range is smaller over oceans than over land

    • Temperature range is smaller over oceans than over land due to the high specific heat capacity of water, ocean currents, and the absence of vegetation and buildings on the ocean surface. This means that oceans can absorb more heat from the sun, release it more slowly and have more homogeneous surface.
  • Where is the temperature range largest? Explain why.

    • The temperature range is the largest in east russia and north canada. The cause for this is the tilt of the earth axis and the presence of land in this regions in comparison to the southern hemisphere. During winter this regions have the polar night and dont get any energy by the sunlight. In summertime this regeions are influenced by monthlong sun irradiance which is absorbed by the dark surface of the ground.

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.

1
2
ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_tp.nc')
ds
<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]
  • 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'

1
2
3
4
5
#convert unit from m to mm
ds = ds.assign(tp = ds['tp']*1000)

#group data by month and average it
ds_month = ds.groupby(ds.time.dt.month).mean()
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
#select data for January and August
ds_jan = ds_month.sel(month = 1)
ds_aug = ds_month.sel(month = 8)

#Plot average precipitation for January
ax = plt.axes(projection=ccrs.Robinson())
ds_jan.tp.plot(ax=ax, transform=ccrs.PlateCarree(), levels=[0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40], cmap = 'YlGnBu', 
               cbar_kwargs={'label': 'precipitation (mm/d)'})
plt.title('Average daily precipitation in January')
ax.coastlines(); ax.gridlines(); 
No description has been provided for this image
1
2
3
4
5
6
#plot average precipitation for August
ax = plt.axes(projection=ccrs.Robinson())
ds_aug.tp.plot(ax=ax, transform=ccrs.PlateCarree(), levels=[0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40], cmap = 'YlGnBu', 
               cbar_kwargs={'label': 'precipitation (mm/d)'}) 
plt.title('Average daily precipitation in August')
ax.coastlines(); ax.gridlines(); 
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)

The ITCZ is the dark blue line indicating heavy precipitation that goes around the globe close to the equator in both graphs. It is a zone where the trade winds converge, it varies seasonally because the sun shifts between hemispheres (Ban 2022, Chapter 1, slide 14).

It moves southwards during winter because there is more sun in the southern hemisphere and vice versa in summer.

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

In West Africa and India you can see on the precipitation maps above that there is a lot of precipitation during August and very little precipitation in January. The effect causing that is called monsoon.

During the summer months the continents are warming faster than the ocean, which causes a low pressure area over the continent that induces a flow from the sea to the continent which transports a lot of moist air, that is responsible for the precipitation, this effect reverses during winter (Goosse et al., 2010, Chapter 1 p. 7).

Part 3: sea-level pressure and surface winds¶

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

1
ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_uvslp.nc')

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).

1
2
#convert to hPa
ds = ds.assign(msl = ds['msl']/100)
1
2
3
4
5
6
ds.msl.mean(dim=['longitude', 'time']).plot()
plt.axhline(1013.25, color = 'red', linestyle = '--')
plt.xlim([-90, 90])
plt.title('Temporal and zonal average of sea-level pressure')
plt.xlabel('latitude (degree north)')
plt.ylabel('pressure (hPa)');
No description has been provided for this image

Question 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.

In the southern hemisphere between about -90° and -80° north the polar high is visible, in the south it still is lower than the global mean sea level pressure. Between -80° and about -45° the sup-polar low is visible causing precipitation year round. Between -45° and -15° there is the subtropical high and then between about -15° and 15° the equatorial low is visible, which causes year round precipitation. In the northern hemisphere the same pattern is visible (Ban 2022, Chapter 1, Slide 20)

1
2
3
4
5
6
7
ds.u10.mean(dim=['longitude', 'time']).plot()
plt.axhline(0, color = 'red', linestyle = '--')
plt.xlim([-90, 90])
plt.ylim([-7, 7])
plt.title('Temporal and zonal average of the u-component of wind')
plt.xlabel('latitude (degree north)')
plt.ylabel('wind speed (m/s)');
No description has been provided for this image
1
2
3
4
5
6
7
ds.v10.mean(dim=['longitude', 'time']).plot()
plt.axhline(0, color = 'red', linestyle = '--')
plt.xlim([-90, 90])
plt.ylim([-7, 7])
plt.title('Temporal and zonal average of the v-component of wind')
plt.xlabel('latitude (degree north)')
plt.ylabel('wind speed (m/s)');
No description has been provided for this image
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
fig, ax = plt.subplots()

# Plot on the first axis as usual
ax.plot(ds.latitude, ds.msl.mean(dim=['longitude', 'time']), label='mean sea level pressure')
plt.axhline(1013.25, color = 'black', label = 'standard atmospheric pressure (1013.25 hPa)')
plt.ylim([980, 1046.5])
plt.xlim([-90, 90])

# Add a twin axis to the right and plot on it
axr = ax.twinx()
axr.plot(ds.latitude, ds.u10.mean(dim=['longitude', 'time']), color='C1', label='u-component', linestyle = '--');
axr.plot(ds.latitude, ds.v10.mean(dim=['longitude', 'time']), color='C2', label='v-component', linestyle = '--');
plt.ylim([-7, 7])

# Add the legend for both axis
ax.legend(loc='lower left')
axr.legend(loc='lower right')

# Labels and titles
ax.set_xlabel('latitude (degree north)')
ax.set_ylabel('pressure (hPa)')
axr.set_ylabel('wind speed (m/s)')
ax.set_title('Mean sea level pressure in comparison to wind speeds');
No description has been provided for this image

Question 2:

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

In general the winds on the southern hemisphere are stronger than on the northern hemisphere. The reason for that is that there is more land mass on the northern hemisphere causing surface friction and slowing down the wind.

Around the ITCZ, where the v-component is zero close to the equator, there is a westwards wind that increases in south- and northward direction with maximums at about -20° and 20° north. These are the northeast trade winds in the northern hemisphere and the southeast trade winds in the southern hemisphere (Ban, 2022, chapter 1, slide 17). In both hemispheres they are blowing towards the ITCZ where they converge. This is caused by the equatorial low that is surrounded by the subtropical highs.

In both hemispheres the westerlies lie approximately between 65 and 30 degrees and blow in an western polewards direction (Marshall et al., 2008, p. 74). They are caused by the sub-polar low and the subtropical high.

Around the poles the polar high in combination with the sub-polar low induces an equatorward eastwind.

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:

1
df = pd.read_csv('co2_mm_gl.csv', skiprows=55, parse_dates={'date' : [0, 1]}, index_col='date')

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).

Questions:

  1. Describe and explain the annual cycle of CO$_2$ concentrations
  2. 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.
  3. 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.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
##1
##plot the monthly global CO2 concentration as a function of time.

# group the data by month
monthly_co2 = df

# plot the monthly CO2 concentration
monthly_co2["average"].plot()

# add labels and title
plt.xlabel('Month')
plt.ylabel('CO2 Concentration (ppm)')
plt.title('Monthly Global CO2 Concentration')
plt.show()
No description has been provided for this image
  1. Describe and explain the annual cycle of CO$_2$ concentrations
    • This cycle is also caused by the seasonal diffrences of solar irradiance in the upper nothern hemispehere. This change in sunlight changes the photosyntesis of the plants and trees in sibiria and north america. In the southern hemisphere the landmass and thus there is lesser flora to convert CO$_2$ to O$_2$.
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
##2
##group data by year and calculate the mean CO2 concentration for each year

#calculate average annual CO2 concentration 
co2_annual_avg = df.resample('y').mean()

# plot the annual average CO2 concentration
co2_annual_avg["average"].plot()
plt.xlabel("Year")
plt.ylabel("CO2 concentration (ppm)")
plt.title("Annual Average CO2 Concentration")
plt.show()
No description has been provided for this image
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
##3
##plot the annual average timeseries of global CO2 concentration and of global 2m temperature from ERA5 on the same plot (using a secondary y axis for temperature).

#Cut the last 4 years out, because the temperature data is only avaible for 1979-2018
co2_97_18 = pd.read_csv('co2_mm_gl.csv', skiprows=55, skipfooter=46, parse_dates={'date' : [0, 1]}, index_col='date')

#create a new annual avg
co2_annual_avg_2 = co2_97_18.resample('y').mean()
co2_annual_avg_2 

# Meridional weights
weight = np.cos(np.deg2rad(ds.latitude))
weight = weight / weight.sum()

# Meridionally weighted zonal mean
zonal_mean_t2 = ds_t.mean(dim='longitude') - 273.15
weighted_zonal_mean_t2 = zonal_mean_t2 * weight
weighted_ts_t2 = weighted_zonal_mean_t2.sum(dim='latitude')

#Annual weighted zonal mean
weighted_ts_t2_annual = weighted_ts_t2.groupby('time.year').mean(dim='time')
weighted_ts_t2_annual_array = weighted_ts_t2_annual.to_dataframe()

# create a figure and axis
fig, ax1 = plt.subplots()

# plot the annual average CO2 concentration on the first y axis
ax1.plot(co2_annual_avg_2.index, co2_annual_avg_2["average"],label='Annual average CO2 concentration', color='black')
ax1.set_xlabel('Year')
ax1.set_ylabel('CO2 concentration (ppm)', color='black')
ax1.tick_params(axis='y', labelcolor='black')

# add a second y axis for temperature
ax2 = ax1.twinx()

# plot the annual average temperature on the second y axis
ax2.plot(co2_annual_avg_2.index, weighted_ts_t2_annual_array.t2m, label='Annual average temperature' ,color='red')
ax2.set_ylabel('Temperature (Celsius)', color='black')
ax2.tick_params(axis='y', labelcolor='black')


# Add the legend for both axis
ax1.legend(loc='upper left')
ax2.legend(loc='lower right')

# show the plot
plt.title("Annual Average CO2 Concentration and Temperature")
plt.show()
No description has been provided for this image
  1. 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.
    • The CO$_2$ concentration int he pre-industrial era was consistently at 280ppm (Theo Stein, NOAA)
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
# Compute the average CO2 concentration for each year between 1980 and 1985
co2_1980_1985 = co2_annual_avg[(co2_annual_avg.index.year >= 1980) & (co2_annual_avg.index.year <= 1985)]

# Compute the annual increase in CO2 concentration for the years between 1980 and 1985
co2_increase_1980_1985 = co2_1980_1985.diff()

# Compute the average CO2 concentration for each year between 2016 and 2021
co2_2016_2021 = co2_annual_avg[(co2_annual_avg.index.year >= 2016) & (co2_annual_avg.index.year <= 2021)]

# Compute the annual increase in CO2 concentration for the years between 2016 and 2021
co2_increase_2016_2021 = co2_2016_2021.diff()

# Print the results
print(co2_increase_1980_1985["average"])

print(co2_increase_2016_2021["average"])
date
1980-12-31         NaN
1981-12-31    1.199167
1982-12-31    0.745833
1983-12-31    1.673333
1984-12-31    1.543333
1985-12-31    1.465000
Freq: A-DEC, Name: average, dtype: float64
date
2016-12-31         NaN
2017-12-31    2.156667
2018-12-31    2.392500
2019-12-31    2.461667
2020-12-31    2.370833
2021-12-31    2.266667
Freq: A-DEC, Name: average, dtype: float64
  1. 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.
    • The relationship between global temperatures and CO2 concentrations is that CO2 is a greenhouse gas which traps heat from the sun and causes the planet to warm up. Human activities like burning fossil fuels and deforestation are primarily responsible for increasing the CO2 concentration in the atmosphere. Volcanic eruptions, solar variability, and ocean currents can also impact global temperature by emitting aerosols, changing energy from the sun reaching the earth and altering heat transport through ocean currents.

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

Using the available data, describe the global effect of an El Niño year and a La Niña year on sea-surface temperature, precipitation, and air temperature. I 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. Then use annual or seasonal anomaly maps to show the patterns of SST, temperature and precipitation anomalies during these events. With citation or links, explain why you picked these years as examples.

We decided to work with the El Nino 1997/1998 and the La Nina event 1998/1999, because that was the strongest El Nino event in the past 40 years(Gergis and Fowler, 2009).

Sea Surface Temperature¶

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_sst.nc')

#select data from 1997
ds_97 = ds.sel(time = slice('1997-01', '1997-12'))

#calculate anomally
an_97 = ds_97.sst.mean(dim='time') - ds.sst.mean(dim = 'time')

#create plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
plt.suptitle('Anomally of the sea surface temperature in the El Nino year 1997')
plt.subplots_adjust(top=1)

#Robinson projection
ax1 = plt.subplot(121, projection=ccrs.Robinson())
ax1.coastlines()
im1 = an_97.plot.imshow(ax=ax1, x='longitude', y='latitude', transform=ccrs.PlateCarree(), add_colorbar=False)

#Orthographic procection
ax2 = plt.subplot(122, projection=ccrs.Orthographic(central_longitude=-150, central_latitude=0.0, globe=None))
ax2.coastlines()
im2 = an_97.plot.imshow(ax=ax2, x='longitude', y='latitude', transform=ccrs.PlateCarree(), 
                        add_colorbar=True, cbar_kwargs={'label':"Temperature anomaly (°C)", 'shrink':0.6})
No description has been provided for this image

During the El Nino year 1997 the sea surface temperature at the South American westcoast and in the center of the tropic ocean is up to 3°C higher than usually. At the Indonesian coast it is about 1°C colder than usual. This origins directly from the El Nino effect where warm surface water that is usually pushed westward towards the Indonesian coast by the trade winds upwells in the center of the tropic ocean.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#select data from 1999
ds_99 = ds.sel(time = slice('1999-01', '1999-12'))

#calculate anomally
an_99 = ds_99.sst.mean(dim='time') - ds.sst.mean(dim = 'time')

#create plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
plt.suptitle('Anomally of the sea surface temperature in the La Nina year 1999')
plt.subplots_adjust(top=1)

#Robinson projection
ax1 = plt.subplot(121, projection=ccrs.Robinson())
ax1.coastlines()
im1 = an_99.plot.imshow(ax=ax1, x='longitude', y='latitude', transform=ccrs.PlateCarree(), add_colorbar=False)

#Orthographic procection
ax2 = plt.subplot(122, projection=ccrs.Orthographic(central_longitude=-150, central_latitude=0.0, globe=None))
ax2.coastlines()
im2 = an_99.plot.imshow(ax=ax2, x='longitude', y='latitude', transform=ccrs.PlateCarree(), 
                        add_colorbar=True, cbar_kwargs={'label':"Temperature anomaly (°C)", 'shrink':0.6})
No description has been provided for this image

In contrast to that in the La Nina year 1999 the effect above is amplified and the sea surface temperature at the Indonesian coast is about 1°C warmer than usual and the water at the South American coast and in the center of the tropic ocean is up to 3°C cooler than in the normal state.

Precipitation¶

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
#precipitation anomally
ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_tp.nc')

#convert unit from m to mm
ds = ds.assign(tp = ds['tp']*1000)

#select data from 1997
ds_97 = ds.sel(time = slice('1997-01', '1997-12'))

#calculate anomally
an_97 = ds_97.tp.mean(dim='time') - ds.tp.mean(dim = 'time')

#create plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
plt.suptitle('Anomally of the Precipitation in the El Nino year 1997')
plt.subplots_adjust(top=1)


#Robinson projection
ax1 = plt.subplot(121, projection=ccrs.Robinson())
ax1.coastlines()
im1 = an_97.plot.imshow(ax=ax1, x='longitude', y='latitude', transform=ccrs.PlateCarree(), add_colorbar=False)

#Orthographic procection
ax2 = plt.subplot(122, projection=ccrs.Orthographic(central_longitude=-150, central_latitude=0.0, globe=None))
ax2.coastlines()
im2 = an_97.plot.imshow(ax=ax2, x='longitude', y='latitude', transform=ccrs.PlateCarree(), 
                        add_colorbar=True, cbar_kwargs={'label':"Precipitation anomaly (mm)", 'shrink':0.6})
No description has been provided for this image

During the El Nino year the precipitation at the South American westcoast and in the center of the Tropic Ocean was highly increased while it strongly decreased at the Indonesian coast. The precipitation in Indonesia was so low that there were drought conditions. In general, the event led to below-average precipitation in the western Pacific and above-average precipitation in the eastern Pacific, as well as parts of North and South America.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#select data from 1999
ds_99 = ds.sel(time = slice('1999-01', '1999-12'))

#calculate anomally
an_99 = ds_99.tp.mean(dim='time') - ds.tp.mean(dim = 'time')

#create plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
plt.suptitle('Anomally of the Precipitation in the La Nina year 1999')
plt.subplots_adjust(top=1)


#Robinson projection
ax1 = plt.subplot(121, projection=ccrs.Robinson())
ax1.coastlines()
im1 = an_99.plot.imshow(ax=ax1, x='longitude', y='latitude', transform=ccrs.PlateCarree(), add_colorbar=False)

#Orthographic procection
ax2 = plt.subplot(122, projection=ccrs.Orthographic(central_longitude=-150, central_latitude=0.0, globe=None))
ax2.coastlines()
im2 = an_99.plot.imshow(ax=ax2, x='longitude', y='latitude', transform=ccrs.PlateCarree(), 
                        add_colorbar=True, cbar_kwargs={'label':"Precipitation anomaly (mm)", 'shrink':0.6})
No description has been provided for this image

While the La Nina event 1999 the precipitation above the entire area between the South American coast and the Indonesian coast strongly decreased and the precipitation over Indonesia highly increased. The event generally led to above-average precipitation in the western Pacific and below-average precipitation in the eastern Pacific, as well as in parts of North and South America.

Temperature 2m above surface¶

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#t2m data
#read data
ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_t2m.nc')

#t2m anomally
#select data from 1997
ds_97 = ds.sel(time = slice('1997-01', '1997-12'))

#calculate anomally
an_97 = ds_97.t2m.mean(dim='time') - ds.t2m.mean(dim = 'time')

#create plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
plt.suptitle('Anomally of the surface temperature in the El Nino year 1997')
plt.subplots_adjust(top=1)


#Robinson projection
ax1 = plt.subplot(121, projection=ccrs.Robinson())
ax1.coastlines()
im1 = an_97.plot.imshow(ax=ax1, x='longitude', y='latitude', transform=ccrs.PlateCarree(), add_colorbar=False)

#Orthographic procection
ax2 = plt.subplot(122, projection=ccrs.Orthographic(central_longitude=-150, central_latitude=0.0, globe=None))
ax2.coastlines()
im2 = an_97.plot.imshow(ax=ax2, x='longitude', y='latitude', transform=ccrs.PlateCarree(), 
                        add_colorbar=True, cbar_kwargs={'label':"Temperature anomaly (°C)", 'shrink':0.6})
No description has been provided for this image

The El Nino event 1997 caused an increase in the yearly annual average temperature in many places of the world

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
#select data from 1999
ds_99 = ds.sel(time = slice('1999-01', '1999-12'))

#calculate anomally
an_99 = ds_99.t2m.mean(dim='time') - ds.t2m.mean(dim = 'time')

#create plot
fig, (ax1, ax2) = plt.subplots(1, 2, figsize=(10, 5))
plt.suptitle('Anomally of the surface temperature in the La Nina year 1999')
plt.subplots_adjust(top=1)


#Robinson projection
ax1 = plt.subplot(121, projection=ccrs.Robinson())
ax1.coastlines()
im1 = an_99.plot.imshow(ax=ax1, x='longitude', y='latitude', transform=ccrs.PlateCarree(), add_colorbar=False)

#Orthographic procection
ax2 = plt.subplot(122, projection=ccrs.Orthographic(central_longitude=-150, central_latitude=0.0, globe=None))
ax2.coastlines()
im2 = an_99.plot.imshow(ax=ax2, x='longitude', y='latitude', transform=ccrs.PlateCarree(), 
                        add_colorbar=True, cbar_kwargs={'label':"Temperature anomaly (°C)", 'shrink':0.6})
No description has been provided for this image

The 1999 La Nina event had an opposite effect on global surface temperatures when compared to the El Nino event of 1997. During a La Nina event, sea surface temperatures in the equatorial Pacific Ocean become cooler than average.

References¶

Ban, Nikolina (2022), The Climate System, Slides

Gergis, Joëlle L., and Anthony M. Fowler. "A History of ENSO Events since A.D. 1525: Implications for Future Climate Change." Climatic Change 92.3-4 (2009): 343-87. Web.

Goosse H., P.Y. Barriat, W. Lefebvre, M.F. Loutre, and V. Zunz (2010). Introduction to climate dynamics and climate modeling. Online textbook available at http://www.climate.be/textbook

Marshall, Plumb, and Plumb, R. Alan. Atmosphere, Ocean, and Climate Dynamics : An Introductory Text. 2008. Print. International Geophysics Ser.

Theo Stein "Carbon dioxide now more than 50% higher than pre-industrial levels" https://www.noaa.gov/news-release/carbon-dioxide-now-more-than-50-higher-than-pre-industrial-levels