Übertsroider, Wolf

Group project: the Climate System¶

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 11 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 a 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. We 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

We 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)
In [2]:
import matplotlib.pyplot as plt  
import numpy as np  
import xarray as xr 
import pandas as pd  
import cartopy  
import cartopy.crs as ccrs  
import cartopy.feature as cfeature

plt.rcParams['figure.figsize'] = (12, 5)  

Part 1 - temperature climatology¶

Open the ERA5 temperature data:

In [3]:
ds = xr.open_dataset('../Final_Project/ERA5_LowRes_Monthly_t2m.nc')
ds
Out[3]:
<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.

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.
  • That is because the gulf stream brings warm water an thus warm air from the tropics into higher latitudes. This affects the temperatures in Northern Europe.

  • Compared to the gulf stream in the North Atlantic the Northern Pacific Ocean doesn't have such a strong warm stream. There is a warm stream in the Northern Pacific Ocean called the Kurohio current but it doesn't reach such high latitudes and thus has less influence on temperatures at higher latitudes than the gulf strem.

  • That is because the tropics recieve more direct and concentrated solar radiation. This is because the sun is nearly overhead throughout the year, wich leads to consistend day lenghts and heating. Throug that heating the temperature stays consistend over the year (there are also no clearly defined seasons) so the temperature range is samaller.

  • The temperature range over water is samller than over land because land heats and cools easier than water does. This is because of the high specific heat capacity of water Therefore the watertemperature doesn't change strongly

  • The temperature range is largest in siberia, that results from a combination of arctic influences, continental climate, snow cover and the geographic location. Siberia is located at high latitudes, this results in a more pronounced difference between summer and winter temperatures due to the tilt of the Earth's axis.

In [4]:
fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )



temp_mean_C = ds['t2m'].mean(dim = 'time').values-273.15
contour = ax.contourf(ds['longitude'], ds['latitude'], temp_mean_C, transform=ccrs.PlateCarree())
gl = ax.gridlines(draw_labels=True)
cbar = plt.colorbar(contour, ax=ax)
cbar.set_label('Temperature in °C')
ax.set_title('Temporal mean Temperature')
plt.show()
In [5]:
zonal_anomaly = ds['t2m'].mean(dim='time') - ds['t2m'].mean(dim=['time', 'longitude'])


fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )

levels = np.arange(zonal_anomaly.min().round()-1,zonal_anomaly.max().round()+2,2)

contour = ax.contourf(ds['longitude'], ds['latitude'], zonal_anomaly, transform=ccrs.PlateCarree(),levels = levels)
gl = ax.gridlines(draw_labels=True)
cbar = plt.colorbar(contour, ax=ax)
cbar.set_label('Mean Temperature in °C')
ax.set_title('Zonal temperature anomaly')
plt.show()
In [6]:
#compute annual cylcle
month_aver_temp = ds['t2m'].groupby('time.month').mean()

x = month_aver_temp['month']
y = month_aver_temp.mean('longitude').mean('latitude')-273.15

plt.xlabel('Month')
plt.ylabel('Average Temperature in °C')
plt.title('Monthly average Temperature')
plt.xticks(x)

plt.plot(x,y)


plt.show()
In [7]:
fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )

#range
temp_range = (ds['t2m'].groupby('time.month').max()-ds['t2m'].groupby('time.month').min()).mean('month')
contour = ax.contourf(ds['longitude'], ds['latitude'], temp_range, transform=ccrs.PlateCarree())
gl = ax.gridlines(draw_labels=True)
cbar = plt.colorbar(contour, ax=ax)
cbar.set_label('Temperature in °C')

ax.set_title('Average monthly temperature range')
plt.show()

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 [8]:
ds_prec = xr.open_dataset('../Final_Project/ERA5_LowRes_Monthly_tp.nc')

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'

Questions:

  1. Describe the location of the ITCZ in January and February. Without going into the details, explain (in one or two sentences)
  2. Describe the precipitation seasonality in West Africa and in India. Name the phenomenon at play.
  1. In January, the Intertropical Convergence Zone (ITCZ) is generally situated near or over the equator. By August, it tends to shift northward, reaching a position closer to the northern hemisphere, due to the seasonal movement of the sun. (We assume you have a typo in your question and meant January and Agust because of the plots)

  2. West Africa experiences more precipitation in August than in June, this is called the West African Monsoon. This happens because the (ITCZ) shifts northward and brings heavy rains.

In India it's a similar pattern and is known as Indian Monsoon.

In [9]:
average_prec = ds_prec['tp'].groupby('time.month').mean()
average_prec_in_mm = average_prec *1000
average_prec_in_mm_grouped = average_prec_in_mm.groupby('month')


#create map
fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )
gl = ax.gridlines(draw_labels=True)

levels = (0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40)

#plot january
contour_prec_jan = ax.contourf(ds['longitude'],ds['latitude'],average_prec_in_mm_grouped[1], transform=ccrs.PlateCarree(), levels = levels, cmap = 'YlGnBu')
cbar = plt.colorbar(contour_prec_jan, ax=ax)
cbar.set_label('Precipitation in mm/day')
ax.set_title('Daily average precipitation January')

#create map
fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )
gl = ax.gridlines(draw_labels=True)

#plot august
contour_prec_aug = ax.contourf(ds['longitude'],ds['latitude'],average_prec_in_mm_grouped[8], transform=ccrs.PlateCarree(), levels = levels, cmap = 'YlGnBu')
cbar = plt.colorbar(contour_prec_aug, ax=ax)
cbar.set_label('Precipitation in mm/day')
ax.set_title('Daily average precipitation August')

plt.show()

Part 3: sea-level pressure and surface winds¶

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

In [10]:
ds_winds_and_msl = xr.open_dataset('../Final_Project/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).

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.
  2. Similarly, explain the direction and strength of the zonal and meridional winds on earth (tip: the sea-level pressure plot helps)
  1. As we can see at -30° and 30° we have high pressure systems wich are known as the subtropical highs (between hadley cell and ferrell cell)
    At -60° and 60° we can see low pressure systems (the one at -60° is way stronger because there is not that much landmass in the south) wich are known as the subpolar lows (between ferrell cell and polar cell)
    At the poles we usually have high pressure systems wich are very weak

  2. Zonal winds move along east west. They arise at the equator due to warm rising air at the ITCZ generating lows resulting into east west trade winds. In the subtropics descending air from the hadley cell forms subtropical highs contributing to trade winds. In mid-latitudes westerlies prevail due to ferrell cell circulation.

Meridional winds move along north south. More significant flow occurs, especially in regions with strong pressure gradients, such as the polar front. In polar regions meridional flow is influenced by the polar easterlies and westerlies. These winds arise from diffrences in sea-level pressure, shaped by solar heating and influenced by the Coriolis effect induced by the Earth's rotation.

In [11]:
#temporal average
temporal_average = (ds_winds_and_msl['msl'].mean('time'))/100

#zonal average
zonal_average = ( ds_winds_and_msl['msl'].mean(['longitude','time']))/100

y1 = temporal_average
y2 = zonal_average
x = ds_winds_and_msl['latitude']
plt.plot(x,y1,color = 'Blue')
plt.plot(x,y2,color = 'Red')
plt.title('Zonal average (Red) and Temporal average (Blue) of sea level pressure')
plt.ylabel('Pressure in hPa')
plt.xlabel('Latitude')

plt.axhline(1013.25,color='Green', linestyle='--', label = 'Standard atmospher pressure (hPa)')

# Add the value on the y-axis
plt.text(x.min()-10, 1013.25, f'{1013.25}', va='center', ha='right', color='Green')

plt.legend(loc = 'lower right')
plt.show()
In [23]:
#temporal average for u10 and v10 
temporal_average_u10 = ds_winds_and_msl['u10'].mean('time')
temporal_average_v10 = ds_winds_and_msl['v10'].mean('time')

#zonal average for u10 and v10
zonal_average_u10 = ds_winds_and_msl['u10'].mean(['longitude', 'time'])
zonal_average_v10 = ds_winds_and_msl['v10'].mean(['longitude', 'time'])


#plotting u10

plt.plot(ds_winds_and_msl['latitude'], temporal_average_u10, color='Blue')
plt.plot(ds_winds_and_msl['latitude'], zonal_average_u10, color='Red')

plt.title('Zonal average (Red) and Temporal average (Blue) Wind Components (u10)')
plt.ylabel('Wind Speed (m/s)')
plt.xlabel('Latitude')

plt.axhline(0, color='Green', linestyle='--', label='Zero Wind Line')
plt.legend()
plt.show()

#plotting v10

plt.plot(ds_winds_and_msl['latitude'], temporal_average_v10, color='Blue')
plt.plot(ds_winds_and_msl['latitude'], zonal_average_v10, color='Red')

plt.title('Zonal average (Red) and Temporal average (Blue) Wind Components (v10)')
plt.ylabel('Wind Speed (m/s)')
plt.xlabel('Latitude')

plt.axhline(0, color='Green', linestyle='--', label='Zero Wind Line')
plt.legend()
plt.show()

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 [13]:
df = pd.read_csv('../Final_Project/co2_mm_gl.csv', skiprows=38, parse_dates={'date' : [0, 1]}, index_col='date',date_format = '%Y %m')
df
# we canged the skiprows to 38 to use all data and get a reasonable head
Out[13]:
decimal average average_unc trend trend_unc
date
1979-01-01 1979.042 336.56 0.11 335.92 0.09
1979-02-01 1979.125 337.29 0.09 336.25 0.10
1979-03-01 1979.208 337.88 0.11 336.51 0.10
1979-04-01 1979.292 338.32 0.12 336.72 0.10
1979-05-01 1979.375 338.26 0.03 336.71 0.10
... ... ... ... ... ...
2023-05-01 2023.375 420.54 0.10 418.87 0.06
2023-06-01 2023.458 419.53 0.10 418.94 0.06
2023-07-01 2023.542 417.83 0.10 419.10 0.06
2023-08-01 2023.625 416.53 0.10 419.36 0.06
2023-09-01 2023.708 416.83 0.10 419.70 0.06

537 rows × 5 columns

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. The annual cycle of CO$_2$ concentrations is shaped from the seasons. In spring and early summer when plants beginn to grow they absorb CO$_2$. In late summer and fall plants die or drop leaves what releases CO$_2$. In winter plants barely do photosynthesis so there is no absorbtion of CO$_2$. The annual cycle is more pronounced in the Northern Hemisphere due to the larger landmasses and vegetation cover. Of course humanity has a large impact on the annual CO$_2$ conentration by combusting fossil fuels.

  2. In the pre-industrial era in the mid-1700s, atmospheric carbon dioxide was 280 ppm or less.

The annual increase in CO2 between 1980 and 1985 is 1.3251666666666666 ppm per year The annual increase in CO2 between 2021 and 2016 is 2.3273333333333426 ppm per year

  1. Greenhouse gases trap some of the outgoing infrared radiation from the Earth's surface, preventing it from escaping into space.

Increased concentrations of CO$_2$ in the atmosphere enhance the greenhouse effect, leading to more heat being trapped. This results in a warming of the Earth's surface.

  • Solar Radiation Variability:

Changes in solar radiation, such as variations in the Sun's output or changes in Earth's orbit, can influence global temperatures. Though these variations are relatively small over short timescales, they can contribute to climate variability.

  • Ocean Circulation Patterns:

Ocean currents play a crucial role in redistributing heat around the planet. Changes in ocean circulation, such as El Niño and La Niña events, can significantly impact regional and global temperatures. For instance, El Niño tends to bring warmer conditions, while La Niña can lead to cooler temperatures in some regions

  • Land Use Changes:

Alterations in land cover, such as deforestation or urbanization, can affect local and regional climates. Changes in land use influence the absorption and reflection of solar radiation, impacting temperatures in the modified areas.

In [14]:
df_1985 = df[df.index.year == 1985]
co2_1985 = df_1985['average'].mean()
df_1980 = df[df.index.year == 1980]
co2_1980 = df_1980['average'].mean()
co2_conc_1980to1985 = (co2_1985 - co2_1980)/5
print('The annual increase in CO2 between 1980 and 1985 is',co2_conc_1980to1985,'ppm per year')

df_2016 = df[df.index.year == 2016]
co2_2016 = df_2016['average'].mean()
df_2021 = df[df.index.year == 2021]
co2_2021 = df_2021['average'].mean()
co2_conc_2016to2021 = (co2_2021 - co2_2016)/5
print('The annual increase in CO2 between 2021 and 2016 is',co2_conc_2016to2021, 'ppm per year')
The annual increase in CO2 between 1980 and 1985 is 1.3251666666666666 ppm per year
The annual increase in CO2 between 2021 and 2016 is 2.3273333333333426 ppm per year
In [15]:
date = df.index
conc = df['average']

#plot
plt.plot(date, conc,label='Monthly CO$_2$ Concentration')
plt.title('Monthly global CO$_2$ concentration')
plt.xlabel('Year')
plt.ylabel('CO$_2$ concentration in ppm')
plt.legend()
plt.show()
In [16]:
# Calculate annual averages
annual_avg = df['average'].resample('A').mean().reset_index()
#plot
plt.figure(figsize=(12, 6))
plt.plot(annual_avg['date'], annual_avg['average'], label='Annual Average CO$_2$ Concentration', marker='o')

plt.xlabel('Year')
plt.ylabel('CO$_2$ Concentration (ppm)')
plt.title('Annual Average Global CO$_2$ Concentration Over Time')

plt.legend()
plt.show()
In [17]:
co2_annual = df['average'].resample('A').mean()
temp_annual = ds['t2m'].resample(time='A').mean(dim='time')

#calculate the global average temperature
global_temp_annual = temp_annual.mean(dim=['latitude', 'longitude'])-273.15

#plot
fig, ax1 = plt.subplots(figsize=(12, 5))

#CO2 concentration plot
ax1.set_xlabel('Year')
ax1.set_ylabel('CO$_2$ Concentration (ppm)')
ax1.plot(co2_annual.index.year, co2_annual, label = 'CO$_2$ Concentration', marker ='o', markeredgewidth = 0.3, markeredgecolor = 'Black')

#create second axis
ax2 = ax1.twinx()
ax2.set_ylabel('Temperature (°C)')
ax2.plot(global_temp_annual['time.year'], global_temp_annual,color='Red', label = 'Temperature', marker = 'o',markeredgewidth = 0.3, markeredgecolor = 'Black')

plt.title('Annual Average Timeseries of Global CO$_2$ Concentration and 2m Temperature (ERA5)')
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')

plt.show()

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.

In [19]:
ds_sst = xr.open_dataset('../Final_Project/ERA5_LowRes_Monthly_sst.nc')

commpared events: el nino 1997 la nina 2010 We picked those two years because there was a very strong el nino and la nina event and those are the closest to today (we also tought about picking el nino of 1982 but we decided it is to far in the past)
We got a brief overview over the events on this chart https://de.wikipedia.org/wiki/El_Ni%C3%B1o-Southern_Oscillation#/media/Datei:SOI.svg

In [20]:
ds_sst_filtered_nino = ds_sst.sel(time=slice('1997-01-01', '1998-12-31')).mean(dim='time')
ds_sst_filtered_nina = ds_sst.sel(time=slice('2010-01-01', '2011-12-31')).mean(dim='time')

#calculate anomalie
ds_sst_nina_nino = ds_sst_filtered_nino['sst'] - ds_sst_filtered_nina['sst']


#plot the difference 
fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )
gl = ax.gridlines(draw_labels=True)


contour_sst_nina_nino = ax.contourf(ds_sst_filtered_nino['longitude'],ds_sst_filtered_nino['latitude'],ds_sst_nina_nino, transform=ccrs.PlateCarree())
cbar = plt.colorbar(contour_sst_nina_nino, ax=ax)
cbar.set_label('Seasurface temperature difference')
plt.title('Seasurface temperature anomalie')
plt.show()

In the plot Seasurface temperature anomalie we can see a strong temperature rise in the Equatorial Pacific, wich we can connect with an El Niño event. When the temperature difference is negative in a region the temperature rises more in an La Niña event.

In [21]:
ds_prec_filtered_nino = ds_prec.sel(time=slice('1997-01-01', '1998-12-31')).mean(dim='time')*1000
ds_prec_filtered_nina = ds_prec.sel(time=slice('2010-01-01', '2011-12-31')).mean(dim='time')*1000

#calculate anomalie
ds_prec_nina_nino = ds_prec_filtered_nino['tp'] - ds_prec_filtered_nina['tp']

#plot diffrence
fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )
gl = ax.gridlines(draw_labels=True)

levels = np.arange(0,ds_prec_nina_nino.max()+1,0.5)

contour_prec_nina_nino = ax.contourf(ds_prec_filtered_nino['longitude'],ds_prec_filtered_nino['latitude'],ds_prec_nina_nino, transform=ccrs.PlateCarree(), levels = levels)
cbar = plt.colorbar(contour_prec_nina_nino, ax=ax)
cbar.set_label('Precipitation in mm/day')
plt.title('Precipitation anomalie')
plt.show()

In the plot Precipitation anomalie we can see how precipitation increses with an El Niño event. On the white spots we have negative precipitation wich means we have stronger precipitation in this regions during an La Niña event.

In [22]:
ds_t2m_filtered_nino = ds.sel(time=slice('1997-01-01', '1998-12-31')).mean(dim='time')
ds_t2m_filtered_nina = ds.sel(time=slice('2010-01-01', '2011-12-31')).mean(dim='time')

#calculate anomalie
ds_t2m_nina_nino = ds_t2m_filtered_nino['t2m'] - ds_t2m_filtered_nina['t2m']


#plot the difference 
fig = plt.figure()
ax = plt.axes(projection=ccrs.Robinson()) 
ax.coastlines(linewidth=0.8)
ax.add_feature(cfeature.BORDERS, linewidth=0.5, edgecolor='black',linestyle=':' )
gl = ax.gridlines(draw_labels=True)


contour_t2m_nina_nino = ax.contourf(ds_t2m_filtered_nino['longitude'],ds_t2m_filtered_nino['latitude'],ds_t2m_nina_nino, transform=ccrs.PlateCarree())
cbar = plt.colorbar(contour_t2m_nina_nino, ax=ax)
cbar.set_label('Air Temperature')
plt.title('Air temperature anomalie')
plt.show()

In the plot Air temperature anomalie we can see similar patterns as in the seasurface temperature anomalie plot.

In [ ]: