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 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 | # 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:
1 2 | dst2m = xr.open_dataset(r'C:\Users\rissb\Desktop\Python\VU Klima\ERA5_LowRes_Monthly_t2m.nc') dst2m.t2m |
<xarray.DataArray 't2m' (time: 480, latitude: 241, longitude: 480)> [55526400 values with 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 * time (time) datetime64[ns] 1979-01-01 1979-02-01 ... 2018-12-01 Attributes: units: K long_name: 2 metre temperature
Dataset of 2m temperature of ERA5. has values for longitude and latitude with a spatial resolution of 0.75° and the average for every month from 01.01.1979 to 01.12.2018
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:
- 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.
- 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.
Compute and plot the temporal mean temperature $\overline{T}$ for the entire period (unit °C)
1 2 3 4 5 6 | t2mbar_entperiod = dst2m.t2m.mean(dim = 'time') - 273.15 ax = plt.axes(projection=ccrs.Robinson()) t2mbar_entperiod.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': '°C'}) ax.coastlines() ax.gridlines() ax.set_title('$\overline{T}$ in °C'); |
Compute and plot $\overline{T^{*}}$ (see lesson), the zonal anomaly map of average temperature.
$\overline{T^{*}}$ is the departure from the zonal average which is calculated $T^{*} = T - \left[ T \right]$ where $T$ is the temperature and $\left[ T \right]$ is the zonal average (mean over latitudes).
1 2 3 | t2mbar_zonalavg = t2mbar_entperiod.mean(dim = 'longitude') t2mbar_zonalavg.attrs["Unit"] = "° Celsius" t2mbarstar_dptzonalavg = (t2mbar_entperiod - t2mbar_zonalavg) |
1 2 3 4 5 | ax = plt.axes(projection=ccrs.Robinson()) t2mbarstar_dptzonalavg.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': '°C'}) ax.coastlines() ax.gridlines() ax.set_title('$\overline{T^{*}}$ in °C'); |
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.
1 2 3 4 | t2m_annualcycle_mean = dst2m.t2m.groupby('time.month').mean() t2m_annualcycle_max = dst2m.t2m.groupby('time.month').max() t2m_annualcycle_min = dst2m.t2m.groupby('time.month').min() t2m_annualcycle_range = (t2m_annualcycle_max - t2m_annualcycle_min).mean(dim = 'month') |
1 2 3 | ax = plt.axes(projection=ccrs.Robinson()) t2m_annualcycle_range.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': '°C'}) ax.coastlines(); ax.gridlines(); ax.set_title('$\overline{T_M}$max - $\overline{T_M}$min'); |
Questions:
- 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.
Due to the North atlantic oscilation there is a higher air pressure above the Azores than to the surroundings (Azores high), near Greenland and Icleand we can find lower air pressure than to surrounding regions (sub-polar low). Furthermore thermohaline circulation brings a warm shallow current into the Atlantic ocean which results in a warmer ocean and air temperature considering the sea-to-air heat transfer. Westerlies bring these warm air masses to northern Europe influencing the t2m temperature. As the ocean has a greater heat capacity than the landmass, the temperature anomly above those regions is positive. Also we have to consider that we have the average zonal temperature anomaly of the last 40 years. Due to the fact that the Arctic Circle had a much greater warming (factor 4) than the surroundings (Rantanen et al. 2022), the range in temperature is much greater. This also leads to a bigger difference in the zonal average compared to Russia and North America.
Sources: https://www.britannica.com/science/North-Atlantic-Oscillation, https://www.usgs.gov/news/unraveling-impacts-north-pacific-and-north-atlantic-ocean-warming-arctic-climate, https://www.ldeo.columbia.edu/res/pi/NAO/, https://earthobservatory.nasa.gov/images/81214/arctic-amplification, https://www.nature.com/articles/s43247-022-00498-3#:%7E:text=During%201979%E2%80%932021%2C%20major%20portions,fast%20as%20the%20global%20average
- Explain why the Northern Pacific Ocean does not have a similar pattern.
NAO is regionally focoused over the North Atlantic and therefore not dominant in the pacific, altough it is closely related to the Arcitc oscillation, which also takes place over the Pacific ocean. Due to the Thermohaline circulation, the northern Atlcatnic ocean is much warmer than at comparable latitudes in the northern Pacific. This explains the smaller anomaly in the map.
Sources: http://www.pik-potsdam.de/~stefan/Publications/Nature/nature_concept_03.pdf
- Look at the average monthly temperature range map.
- Explain why the temperature range is smaller in the tropics than at higher latitudes
As we do not really have seasons in the tropics, the temperature range is significantly lower than in higher latitudes. This is because the tropics are more exposed to solar radiation.
Sources: https://education.nationalgeographic.org/resource/koppen-climate-classification-system, https://education.nationalgeographic.org/resource/tropics
- Explain why the temperature range is smaller over oceans than over land
This effect can be explained with the heat capacity of the ocean. As the ocean has a much bigger heat capacity than landmass, much more energy is needed to warm or cool it down. Therefore the temperature range over oceans is much smaller.
- Where is the temperature range largest? Explain why.
In the polar region the temperature range is the largest. During the polar night there is no solar radiation up to half of a year resulting in low temperatures. That's why the temperature anaomlies can get very big, as solar radiation in the summer can lead to melting of ice, seasonal snow covers and in general higher temperatures.
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 | dstp = xr.open_dataset('../VU Klima/ERA5_LowRes_Monthly_tp.nc') dstp.tp |
<xarray.DataArray 'tp' (time: 480, latitude: 241, longitude: 480)> [55526400 values with 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 * time (time) datetime64[ns] 1979-01-01 1979-02-01 ... 2018-12-01 Attributes: units: m long_name: Total precipitation
ERA5 data giving the daily sums of precipitation from 01.01.1971 to 01.12.2018
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 | tp_avgdailypermonth = (dstp.tp.groupby('time.month').mean()) * 1000 #conversion to mm tp_avgdailypermonth_01 = tp_avgdailypermonth.sel(month = 1) tp_avgdailypermonth_08 = tp_avgdailypermonth.sel(month = 8) |
1 2 3 4 5 6 7 8 9 10 11 12 | ax = plt.axes(projection=ccrs.Robinson()) tp_avgdailypermonth_01.plot(ax=ax, transform=ccrs.PlateCarree(), cmap='YlGnBu', center=False, levels=[0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40], cbar_kwargs={'label': 'mm/day'}) ax.set_title('Average daily precip in January') ax.coastlines(); ax.gridlines(); #August plt.figure(); ax = plt.axes(projection=ccrs.Robinson()) tp_avgdailypermonth_08.plot(ax=ax, transform=ccrs.PlateCarree(), cmap='YlGnBu', center=False, levels=[0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40], cbar_kwargs={'label': 'mm/day'}) ax.set_title('Average daily precip in August') ax.coastlines(); ax.gridlines(); |
Questions:
- Describe the location of the ITCZ (Innertropical Convergence Zone) in January and February. Without going into the details, explain (in one or two sentences)
In January and Febuary the ITCZ over the Pacific and parts of the Atlantic is slightly in the north of the pacific whereas above Africa, the Indian ocean and Australia it is in the south of the equator.
This is because the earth rotates around the sun with an obliquity of 23,5° and therefore the zenith stand changes continously.
- Describe the precipitation seasonality in West Africa and in India. Name the phenomenon at play.
Due to the seasonal shift of the ITCZ, the percipitation connected to it, shifts further northwards in the month June to September and southwards for West Africa and India. The phenomena are called West african Monsoon and Indian monsoon.
Sources: https://www.britannica.com/science/West-African-monsoon, https://www.britannica.com/science/Indian-monsoon
Part 3: sea-level pressure and surface winds¶
Open the file containing the surface winds (u10
and v10
) and sea-level pressure (msl
).
1 2 | ds = xr.open_dataset('../VU Klima/ERA5_LowRes_Monthly_uvslp.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: 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...
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 3 4 5 6 7 | msl_mean_zonalandtime = (ds.msl.mean(dim = 'longitude').mean(dim = 'time') / 100) msl_mean_zonalandtime.plot.line(xlim = (-90, 90)); plt.title('Temporal and zonal average of sea-level pressure'); plt.xlabel('Latitude in °'); plt.ylabel('msl in hPa'); plt.axhline(y = 1013.25, linestyle = 'dotted', color='g'); |
1 2 3 4 5 6 7 | u10_mean_zonalandtime = (ds.u10.mean(dim = 'longitude').mean(dim = 'time')) u10_mean_zonalandtime.plot.line(xlim = (-90, 90)); plt.title('Temporal and zonal average of u10 (positive values are westerlies)'); plt.xlabel('Latitude in °'); plt.ylabel('u10 in m * $s^{-1}$'); plt.axhline(y = 0, linestyle = 'dotted', color='g'); |
1 2 3 4 5 6 7 | v10_mean_zonalandtime = (ds.v10.mean(dim = 'longitude').mean(dim = 'time')) v10_mean_zonalandtime.plot.line(xlim = (-90, 90)); plt.title('Temporal and zonal average of v10'); plt.xlabel('Latitude in °'); plt.ylabel('v10 in m * $s^{-1}$'); plt.axhline(y = 0, linestyle = 'dotted', color='g'); |
Questions:
- 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 circulation system of the earth there are three cells: Hadley, Ferrel and Polar cell. Warm air masses rise at roughly the equator (that's where the sun is in the zenith and therefore the strongest). While the warm air masses rise (low pressure system), it get's colder and moister until it sinks at about 30°N/S (high pressure system, Hadley cell). The Polar cell is driven from warm and moist air rising at 60° N/S which then moves polewards. As the radiation at the pole is lower the air cools and therefore gets heavier and sinks creating a high pressure system at the north and south. The Ferrel cell is located inbetween the Polar and the Headley cell with air rising at 60° N/S and moving equatorwards at altitude and then sinking at 30° N/S moving polewards at surface. Contributing to the low at 60° N/S and high at 30° N/S. These Systems create a climatological low at 0° N/S, 60° N/S and a climatological high at 30° N/S and 90° N/S.
Source: Lecture notes: ComponentsProcesses p. 12-17
- Similarly, explain the direction and strength of the zonal and meridional winds on earth (tip: the sea-level pressure plot helps)
Zonal winds flow from east to west or vice versa and are shown by the u10 plot. Meridional winds flow from north to south and so are detected by the v10 plot. In both cases coriolis needs to be considered and leads to a deflection of the actual direction to the right of their heading. As pressure differences create winds in the earths atmosphere we can quite well see where the winds are stronger (higher pressure diffrence) or weaker (lower pressure difference). Having a look at the sea surface pressure map this relationship can be seen very clearly. All the cells of the general atmospheric circulation and the deflection of the winds due to coriolis can be seen in the plot.
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 2 | df = pd.read_csv('../VU Klima/co2_mm_gl.csv', skiprows=55, parse_dates={'date' : [0, 1]}, index_col='date') df |
decimal | average | average_unc | trend | trend_unc | |
---|---|---|---|---|---|
date | |||||
1979-01-01 | 1979.042 | 336.56 | 0.10 | 335.92 | 0.09 |
1979-02-01 | 1979.125 | 337.29 | 0.09 | 336.25 | 0.09 |
1979-03-01 | 1979.208 | 337.88 | 0.10 | 336.51 | 0.09 |
1979-04-01 | 1979.292 | 338.32 | 0.11 | 336.72 | 0.09 |
1979-05-01 | 1979.375 | 338.26 | 0.04 | 336.71 | 0.10 |
... | ... | ... | ... | ... | ... |
2022-05-01 | 2022.375 | 418.43 | 0.10 | 416.79 | 0.06 |
2022-06-01 | 2022.458 | 417.48 | 0.10 | 416.89 | 0.06 |
2022-07-01 | 2022.542 | 415.72 | 0.10 | 417.01 | 0.06 |
2022-08-01 | 2022.625 | 414.38 | 0.10 | 417.22 | 0.06 |
2022-09-01 | 2022.708 | 414.57 | 0.10 | 417.40 | 0.06 |
525 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).
1 | df.average.index |
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', ... '2021-12-01', '2022-01-01', '2022-02-01', '2022-03-01', '2022-04-01', '2022-05-01', '2022-06-01', '2022-07-01', '2022-08-01', '2022-09-01'], dtype='datetime64[ns]', name='date', length=525, freq=None)
1 2 3 4 | #version Hanna für 1: # Monthly global CO_2 concentration as a function of time df.average.plot(xlabel = 'Month', ylabel = '$CO_2$ in ppm', title= 'Monthly global $CO_2$ concentrations'); |
1 2 3 | #Version Hanna annual avg time series: Fabi meint das ist richtig co2_years = df.average.groupby(df.average.index.year).mean() (co2_years).plot(xlabel = 'years', ylabel = '$CO_2$ in ppm', title = 'Annual average timeseries of global $CO_2$ concentration'); |
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)
1 2 3 4 5 6 7 8 9 10 11 12 | #Version Hanna: dst2m = xr.open_dataset('../VU Klima/ERA5_LowRes_Monthly_t2m.nc') # Meridional weights weight = np.cos(np.deg2rad(dst2m.latitude)) weight = weight / weight.sum() # Meridionally weighted zonal mean zonal_mean_t2m_c = dst2m.t2m.mean(dim='longitude') - 273.15 # convert into Celsius weighted_zonal_mean_t2_c = zonal_mean_t2m_c * weight weighted_ts_t2_c = weighted_zonal_mean_t2_c.sum(dim='latitude') |
1 2 3 | #Daten in einen Panda einfügen df2 = weighted_ts_t2_c.to_dataframe(name = 't2m') t2m_years = (df2.t2m.resample('A').mean()) #resample by year |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | #Plot t2m_years and co2_years on the same plot fig, ax = plt.subplots() # Plot on the first axis as usual ax.plot(co2_years.index, co2_years, label='Global $CO_2$ concentration') # Add a twin axis to the right and plot on it axr = ax.twinx() axr.plot(t2m_years.index.year, t2m_years, color='C1', label='Global 2m temperature'); # Add the legend for both axis ax.legend(loc='upper left') axr.legend(loc='lower right') # Labels and titles ax.set_xlabel('Time') ax.set_ylabel('$CO_2$ in ppm') axr.set_ylabel('T in °C') ax.set_title('Annual average timeseries of global $CO_2$ concentration and of global 2m temperature'); |
Questions:
- Describe and explain the annual cycle of CO$_2$ concentrations
Generally CO$_2$ rises in winter and sinks in summer. That's due to the fact that on the northern hemisphere plants grow in spring and summer and absorb the CO$_2$ through photosynthesis and respiration. On the contrary through winter the CO$_2$ concentration rises due to less vegetation. This effect is more dominant on the northern hemisphere due to the land-water distribution of the earth.
- 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 in the pre-industrial era amounts 278 ppm per year. Between 1980 and 1985 the CO$_2$ concentration increased on average by 1.104 ppm per year. Between 2016 and 2021 it already increased by 1.941 ppm per year on average.
1 | co2 = df.average.resample('A').mean() |
1 2 | #Annual mean increase Co2 1980-1985 (unit ppm per year) round((co2['1985-12-31']-co2['1980-12-31'])/6,3) |
1.104
1 2 | #Annual mean increase Co2 2016-2021 (unit ppm per year) round((co2['2021-12-31']-co2['2016-12-31'])/6,3) |
1.941
- 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.
When global CO$_2$ concentrations rise, global temperature rises. This is because CO$_2$ is a greenhouse gas and traps heat in the earths atmosphere. When more CO$_2$ is in the atmosphere more heat is trapped.
+) Rise in Methane CH$_4$ concentration in the atmosphere also acting as a greenhouse gas.
+) Change in the earths albedo, through volcanic eruption, ice melting...
+) Deforestation: less vegetation has a direct influence on the CO$_2$ concentration and changes the temperature at a global scale.
Sources: https://news.climate.columbia.edu/2021/02/25/carbon-dioxide-cause-global-warming/
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.
Global effect of an El Niño on sea-surface temperature, percipitation and air temp:
- When were strong El-Niño events? 1982/83, 1997/98, 2015/16 Quelle: https://www.sciencemediacenter.de/alle-angebote/science-response/details/news/wie-entwickeln-sich-la-nina-und-el-nino-im-klimawandel/#:~:text=Die%20drei%20st%C3%A4rksten%20El%2DNi%C3%B1o,von%20Verschiebungen%20der%20globalen%20Wettersysteme. La Niña:1974-76, 1999-2001
Regarding to this source, we chose the time range 1995 to 2003. Firstly we plotted the gloabl average to get an overview of our data and the global impact of ENSO. Thereby we found it striking, how clearly a temperature and percipitation rise can be seen during the winter of 1997/98. Based on this plot, we decided to pick the month November to April for the anamoly map for El Niño. On the other hand the effect of La Niña cannot be seen so clearly in a global average map. After some research, we also didn't find any particular months, which are very typical or representive for La Niña. That's why we decided to choose the entire 3 years (1999-2001) for the anomaly map.
1 2 3 4 | #Load data df_sst = xr.open_dataset('../VU Klima/ERA5_LowRes_Monthly_sst.nc') df_tp = xr.open_dataset('../VU Klima/ERA5_LowRes_Monthly_tp.nc') df_t2m = xr.open_dataset('../VU Klima/ERA5_LowRes_Monthly_t2m.nc') |
1 2 3 | tp = df_tp.tp sst = df_sst.sst t2m = df_t2m.t2m |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | # Meridional weights weight = np.cos(np.deg2rad(ds.latitude)) weight = weight / weight.sum() # Meridionally weighted zonal mean for sst zonal_mean_sst_c = sst.mean(dim='longitude') - 273.15 # convert into Celsius weighted_zonal_mean_sst_c = zonal_mean_sst_c * weight weighted_sst_c = weighted_zonal_mean_sst_c.sum(dim='latitude') # Meridionally weighted zonal mean for tp zonal_mean_tp = tp.mean(dim='longitude') * 1000 #conversion into mm weighted_zonal_mean_tp = zonal_mean_tp * weight weighted_tp = weighted_zonal_mean_tp.sum(dim='latitude') |
1 2 3 4 5 6 7 8 | sst_a = weighted_sst_c sst_a.sel(time = slice('1995', '2002')).plot(color = 'deepskyblue') sst_a.sel(time = slice('1997-11', '1998-04')).plot(color = 'red', label = 'Wintermonate El Niño' ) sst_a.sel(time = slice('1999', '2001')).plot(color = 'darkblue', label = 'La Niña Jahre' ) #peaks.sel(time = slice('1995', '2002')).plot() plt.title('Global mean sea surface temperature') plt.ylabel('degrees in °C') plt.legend(); |
1 2 3 4 5 6 7 8 | tp_a = weighted_tp tp_a.sel(time = slice('1995', '2002')).plot(color = 'deepskyblue') tp_a.sel(time = slice('1997-11', '1998-04')).plot(color = 'red', label = 'Wintermonate El Niño' ) tp_a.sel(time = slice('1999', '2001')).plot(color = 'darkblue', label = 'La Niña Jahre' ) #peaks.sel(time = slice('1995', '2002')).plot() plt.title('Global total mean precipitation') plt.ylabel('precipitation in mm') plt.legend(); |
1 2 3 4 5 6 | #calculations sst La Nina sst_year = sst.groupby('time.year').mean() sst_year_avg = sst_year.mean(dim='year') sst_avg_period = sst.sel(time = slice('1999', '2001')).mean(dim='time') sst_fluc_nina = (sst_avg_period-sst_year_avg) |
1 2 3 4 5 | #Anomaly map time sst La Nina ax = plt.axes(projection=ccrs.EqualEarth(central_longitude=150)) sst_fluc_nina.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': 'degrees in C'}) ax.coastlines(); ax.gridlines(); ax.set_title('SST anomaly map for 1999-2001 with respect to 1979-2018'); |
1 2 3 4 5 6 | #calculations sst El Nino sst_month = sst.groupby('time.month').mean() sst_month_mean = sst_month.sel(month = [1, 2, 3, 4, 11, 12]).mean(dim='month') sst_avg_period = sst.sel(time = slice('1997-11', '1998-04')).mean(dim='time') sst_fluc_period = sst_avg_period-sst_month_mean |
1 2 3 4 5 | #Anomaly map sst El Nino ax = plt.axes(projection=ccrs.EqualEarth(central_longitude=150)) sst_fluc_period.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': '°C'}) ax.coastlines(); ax.gridlines(); ax.set_title('SST anomaly map Nov-April 1998/99 with respect to Nov-April 1979-2018'); |
1 2 3 4 5 6 | #calculations t2m La Nina t2m_year = t2m.groupby('time.year').mean() t2m_year_avg = t2m_year.mean(dim='year') t2m_avg_period = t2m.sel(time = slice('1999', '2001')).mean(dim='time') t2m_fluc_nina = (t2m_avg_period-t2m_year_avg) |
1 2 3 4 5 | #Anomaly map time t2m La Nina ax = plt.axes(projection=ccrs.EqualEarth(central_longitude=150)) t2m_fluc_nina.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': '°C'}) ax.coastlines(); ax.gridlines(); ax.set_title('T2m anomaly map for 1999-2001 with respect to 1979-2018'); |
1 2 3 4 5 6 | #calculations t2m El Nino t2m_month = t2m.groupby('time.month').mean() t2m_month_mean = t2m_month.sel(month = [1, 2, 3, 4, 11, 12]).mean(dim='month') t2m_avg_period = t2m.sel(time = slice('1997-11', '1998-04')).mean(dim='time') t2m_fluc_period = (t2m_avg_period-t2m_month_mean) |
1 2 3 4 5 | #Anomaly map time tp El Nino ax = plt.axes(projection=ccrs.EqualEarth(central_longitude=150)) t2m_fluc_period.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': '°C'}) ax.coastlines(); ax.gridlines(); ax.set_title('T2m anomaly map Nov-April 1998/99 with respect to Nov-April 1979-2018'); |
1 2 3 4 5 6 | #calculations tp La Nina tp_year = tp.groupby('time.year').mean() tp_year_avg = tp_year.mean(dim='year') tp_avg_period = tp.sel(time = slice('1999', '2001')).mean(dim='time') tp_fluc_nina = (tp_avg_period-tp_year_avg)*1000 #conversion to mm |
1 2 3 4 5 | #Anomaly map time tp La Nina ax = plt.axes(projection=ccrs.EqualEarth(central_longitude=150)) tp_fluc_nina.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': 'mm'}) ax.coastlines(); ax.gridlines(); ax.set_title('Total precipitation anomaly map 1999-2001 with respect to 1979-2018'); |
1 2 3 4 5 6 | #calculations tp El Nino tp_month = tp.groupby('time.month').mean() tp_month_mean = tp_month.sel(month = [1, 2, 3, 4, 11, 12]).mean(dim='month') tp_avg_period = tp.sel(time = slice('1997-11', '1998-04')).mean(dim='time') tp_fluc_period = (tp_avg_period-tp_month_mean)*1000 #conversion into mm |
1 2 3 4 5 | #Anomaly map time tp El Nino ax = plt.axes(projection=ccrs.EqualEarth(central_longitude=150)) tp_fluc_period.plot.imshow(ax=ax, transform=ccrs.PlateCarree(), cbar_kwargs={'label': 'mm'}) ax.coastlines(); ax.gridlines(); ax.set_title('Total Precipitation anomaly map Nov-April 1998/99 with respect to Nov-April 1979-2018'); |