Lorenz Weyh project¶
# Import the tools we are going to need today:
import matplotlib.pyplot as plt # plotting library
import matplotlib.colors as mcolors
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
import cartopy.feature as cfeature
# Some defaults:
plt.rcParams['figure.figsize'] = (12, 5) # Default plot size
All datasets¶
# 2 meter temperature dataset (ds_t2m)
ds_t2m= xr.open_dataset(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\ERA5_LowRes_Monthly_t2m.nc')
# monthly percipitation ds_tp)
ds_tp= xr.open_dataset(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\ERA5_LowRes_Monthly_tp.nc')
# sea level pressure and surface winds (uvslp)
ds_uvslp= xr.open_dataset(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\ERA5_LowRes_Monthly_uvslp.nc')
# CO2 concentration (df)
df = pd.read_csv(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\co2_mm_gl.csv', skiprows=38)
# Combine the first two columns into a datetime column and set as index
df['date'] = pd.to_datetime(df.iloc[:, 0].astype(str) + '-' + df.iloc[:, 1].astype(str), format='%Y-%m')
df.set_index('date', inplace=True)
1 Surface (2m) temperature dataset¶
ds_t2m
<xarray.Dataset> Size: 444MB Dimensions: (longitude: 480, latitude: 241, time: 480) Coordinates: * longitude (longitude) float32 2kB -179.6 -178.9 -178.1 ... 178.9 179.6 * latitude (latitude) float32 964B 90.0 89.25 88.5 ... -88.5 -89.25 -90.0 * time (time) datetime64[ns] 4kB 1979-01-01 1979-02-01 ... 2018-12-01 Data variables: t2m (time, latitude, longitude) float64 444MB ... Attributes: Conventions: CF-1.6 history: 2019-11-18 09:36:58 GMT by grib_to_netcdf-2.14.0: /opt/ecmw...
Anual mean global 2m temperature¶
Compute and plot the temporal mean temperature for the entire period (unit °C)
# compute the mean temperature over time
T_mean_K= ds_t2m.t2m.mean(dim='time')
T_mean_C= T_mean_K-273.15
# plot the mean temperature on a map
ax = plt.axes(projection=ccrs.Robinson())
T_mean_C.plot(ax=ax, transform = ccrs.PlateCarree(),cmap= 'RdBu_r' ,vmin= -50, vmax= 30,levels=9, cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Annual mean global 2m Temperature, ERA5 1979-2018');
#T_mean_C.min().values
Zonal temperature anomaly¶
Compute and plot T* (see lesson), the zonal anomaly map of average temperature.
#compute zonal anomaly values
T2m = ds_t2m.t2m.mean('time')
T_mean= ds_t2m.t2m.mean(dim= ['time', 'longitude'])
T_anomaly= (T2m - T_mean)
norm= mcolors.TwoSlopeNorm(vmin=-30, vcenter=0,vmax=30)
# define the levels for a better looking plot
levels= np.array([-30, -25, -20, -15, -10, -5, 0, 5, 10, 15, 20, 25,30])
# plotting the T anomaly the map
ax = plt.axes(projection=ccrs.Robinson())
T_anomaly.plot(ax=ax, transform = ccrs.PlateCarree(),norm=norm,levels=levels,cmap='RdBu_r',cbar_kwargs={'label':'°C','ticks':levels})
ax.coastlines(); ax.gridlines(); ax.set_title('Zonal 2m Temperature anomaly, ERA5 1979-2018');
#T_anomaly.max().values
#T_anomaly.min().values
Question 1: Explain why northern Europe and the North Atlantic region is significantly warmer than the same latitudes in North America or Russia.
The Nort Atlantic and Northern Europe are significantly warmer than the same latitudes in Russia or North America, because the gulf stream is transporting warm water from the Gulf of Mexico at the surface towards the North Atlantic (https://pubmed.ncbi.nlm.nih.gov/25560606/) (the northern most arms of the gulf stream reach as far north as the fjords of Svalbard). Northern Europe profits from this, because the wind is coming from the west, i.e. the warm and moist gulf stream water reaches Europe (https://www.americanscientist.org/article/the-source-of-europes-mild-climate). Also Russia and North America are much bigger land masses, and so the climate is more continental which results in very cold winters (because land has less energy storing capacity than water), further decreasing the annual average temperatures in those areas (https://www.britannica.com/place/Russia/Climate).
Explain why the Northern Pacific Ocean does not have a similar pattern.
On the US west coast for example, the California current is a cold water current flowing southwards towards the equator. Sea surface temperatures are thus colder(https://www.fleetscience.org/activities-resources/pacific-coast-colder-atlantic-coast). Due to cold ocean temperatures, the westerly winds are also colder in comparison, because they have less energy input from the sea.
Monthly average temperature maps¶
Compute and plot the monthly average temperature for each month TM(annual cycle). We 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 map, i.e. max(TM)-min(TM) (maximum and minimum over the month dimension).
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#January
TM_Jan= TM.sel(month=1)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average January temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#February
TM_Jan= TM.sel(month=2)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average February temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#March
TM_Jan= TM.sel(month=3)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average March temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#April
TM_Jan= TM.sel(month=4)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average April temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#May
TM_Jan= TM.sel(month=5)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average May temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#June
TM_Jan= TM.sel(month=6)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average June temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#July
TM_Jan= TM.sel(month=7)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average July temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#August
TM_Jan= TM.sel(month=8)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average August temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#September
TM_Jan= TM.sel(month=9)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average September temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#October
TM_Jan= TM.sel(month=10)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average October temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#November
TM_Jan= TM.sel(month=11)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average November temperature, ERA5 1979-2018');
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
#December
TM_Jan= TM.sel(month=12)-273.15
ax= plt.axes(projection=ccrs.Robinson())
TM_Jan.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='RdBu_r',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Average December temperature, ERA5 1979-2018');
Monthly average temperature range¶
# calculating the monthly average temperature for each month
TM= ds_t2m.t2m.groupby('time.month').mean(dim='time')
# calculating the temperature range (max-min)
Temp_range= TM.max(dim= 'month')-TM.min(dim='month')
#plotting the result on the map
ax= plt.axes(projection=ccrs.Robinson())
Temp_range.plot(ax=ax, transform= ccrs.PlateCarree(), levels=10,cmap='Oranges',cbar_kwargs={'label':'°C'})
ax.coastlines(); ax.gridlines(); ax.set_title('Monthly average 2m temperature range, ERA5 1979-2018');
#Temp_range.max().values
#Temp_range.min().values
Question 2: Explain why the temperature range is smaller in the tropics than at higher latitudes:
The closer you get to the equator, the less temperature variation you get over the annual cycle. This is because of the tilt of the earth's axis (23.5°) (https://www.ces.fau.edu/nasa/module-3/why-does-temperature-vary/seasons.php) leads to the tropic regions getting more consistent amounts of sunlight and also intensity than the higher latitude regions with pronounced seasons. The year round warm temperatures are producing very moist jungles wich further stabilize the temperature range at low latitudes (https://www.e-education.psu.edu/meteo3/l11_p2.html).
Explain why the temperature range is smaller over oceans than over land:
Water has a higher energy sorage capacity (4184 JKg-1K-1) than land, which helps the oceans to maintain more narrow temperature ranges (https://gml.noaa.gov/education/info_activities/pdfs/LA_radiative_heating_of_land_and_water.pdf).
Where is the temperature range largest? Explain why:
The largest temperature range is found in the north easterly parts of Russia in Sibiria (see on the map). Eurasia is the largest landmass, which makes this part of Russia the most continental area on earth. Additionally, the high latitude is responsible for much sunlight in summer and low sunlight in winter, which further intensifies the variability of temperatures (https://www.britannica.com/place/Russia/Climate, https://www.ces.fau.edu/nasa/module-3/why-does-temperature-vary/seasons.php). For instance, Verkhoyansk has recorded temperature ranges from -68°C in winter to over +38°C in summer, marking one of the most significant annual temperature variations worldwide (https://en.wikipedia.org/wiki/Verkhoyansk).
2 Total precipitation dataset¶
ds_tp
<xarray.Dataset> Size: 444MB Dimensions: (longitude: 480, latitude: 241, time: 480) Coordinates: * longitude (longitude) float32 2kB -179.6 -178.9 -178.1 ... 178.9 179.6 * latitude (latitude) float32 964B 90.0 89.25 88.5 ... -88.5 -89.25 -90.0 * time (time) datetime64[ns] 4kB 1979-01-01 1979-02-01 ... 2018-12-01 Data variables: tp (time, latitude, longitude) float64 444MB ... Attributes: Conventions: CF-1.6 history: 2019-11-18 09:30:18 GMT by grib_to_netcdf-2.14.0: /opt/ecmw...
Average daily precipitation for January and August¶
compute the average daily precipitation for each month of the year (We 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'
# computing the average daily precipitation for each month of the year
avg_pt = ds_tp.tp.groupby('time.month').mean(dim='time')
#print(avg_pt)
avg_pt_mm= avg_pt*1000 # converting the m/day scale to mm/day
#print(avg_pt_mm)
# January selection
levels= np.array([0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40])
avg_pt_mm_Jan= avg_pt_mm.sel(month=1)
# January plot
ax= plt.axes(projection= ccrs.Robinson())
avg_pt_mm_Jan.plot.contourf(ax=ax, transform= ccrs.PlateCarree(), levels=levels, cmap= 'YlGnBu', extend='max',cbar_kwargs={'label':'Precipitation [mm/day]','ticks':levels})
ax.coastlines(); ax.gridlines(); ax.set_title('January average precipitation, ERA5 1979-2018');
# August selection
levels= np.array([0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20, 40])
avg_pt_mm_Aug= avg_pt_mm.sel(month=8)
# August plot
ax= plt.axes(projection= ccrs.Robinson())
avg_pt_mm_Aug.plot.contourf(ax=ax, transform= ccrs.PlateCarree(), levels=levels, cmap= 'YlGnBu', extend='max',cbar_kwargs={'label':'Precipitation [mm/day]','ticks':levels})
ax.coastlines(); ax.gridlines(); ax.set_title('August average daily precipitation, ERA5 1979-2018');
Question 3:
Describe the location of the ITCZ in January and August. Without going into the details, explain (in one or two sentences):
The Intertropical Convergence Zone (ITCZ) shifts seasonally, following the sun's zenith point. In January, it moves south of the equator, extending over regions like South America, Southern Africa, and Northern Australia. By August, the ITCZ shifts northward, positioning itself between 5° and 15° north of the equator over the Atlantic and Pacific Oceans, and even further north over the landmasses of Africa and Asia (see blue band on maps) (https://skybrary.aero/articles/inter-tropical-convergence-zone-itcz).
Describe the precipitation seasonality in West Africa and in India. Name the phenomenon at play.
The phenomena is called monsun. In India in summer, the ITCZ is positioned at a latittude in northern India. The heated up landmass is producing a strong low pressure area, while the indian ocean is producing a high pressure area. The wind is flowing from the ocean north eastwards (i.e. sout-westerly winds) in the direction of India, while taking up a lot of water from the ocean. The air masses are damming up at the Himalayas, leading to very high precipitation over India.
In winter the ITCZ is wandering south, bringing the low pressure areas to South-West Africa. The wind is turning and is now a north-easterly wind, bringing the water masses from the ocean to West Africa and leading to a rain season there. During rain season in India there is a dry season in West Africa and vice versa. (https://www.wetteronline.de/wetterlexikon/monsun)
3 Sea level pressure and surface winds¶
ds_uvslp
<xarray.Dataset> Size: 1GB Dimensions: (longitude: 480, latitude: 241, time: 480) Coordinates: * longitude (longitude) float32 2kB -179.6 -178.9 -178.1 ... 178.9 179.6 * latitude (latitude) float32 964B 90.0 89.25 88.5 ... -88.5 -89.25 -90.0 * time (time) datetime64[ns] 4kB 1979-01-01 1979-02-01 ... 2018-12-01 Data variables: u10 (time, latitude, longitude) float64 444MB ... v10 (time, latitude, longitude) float64 444MB ... msl (time, latitude, longitude) float64 444MB ... Attributes: Conventions: CF-1.6 history: 2019-11-24 19:42:05 GMT by grib_to_netcdf-2.14.0: /opt/ecmw...
Temporal and zonal average sea level preassure [SLP] (hPa)¶
#the temporal and zonal average of sea-level pressure
SLP= ds_uvslp.msl.mean(dim=['time', 'longitude'])/100
SLP.plot(label='temporal and zonal average of sealevel pressure');
plt.axhline(1013.25, label= 'standard atmosphere pressure (1013.25)', color='red')
plt.legend(title='Pressure [hPa]')
plt.ylabel('Pressure [hPa]')
plt.xlabel('latitude [°N]')
plt.grid(False)
plt.title('The temporal and zonal average of sea level pressure, ERA5 1979-2018');
Question: 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.
As can be seen on the line plot above (sea level pressure plot), there are distinct latitude-dependent high and low pressure areas on the planet. Between about 15°S to 15°N, there is the equatorial low pressure belt, caused by continuous intense solar radiation. The warm air is rising in the process called convection. Thick cloud cover and high precipitation is the result of this process.
Subtropical high pressure belts are between 20° - 35° N/S. The warm rising air from the equator is moving polewards at high altitudes. It cools down due to radiative energy loss and the coriolis effect and sinks to the ground, where it heats up again and flows back towards the equatorial area. The high temperatures and low moisture content of the air is creating the high pressure areas.
The low pressure belts starting at ca 50° N/S are caused by warm air from the subtropics and cold air from the polar regions colliding. This is resulting in an upwards motion of the air and unstable weather systems. The diagram shows that the low pressure area of the southern hemisphere is much more pronounced than the one of the northern hemisphere.
The poles are cold and dry, creating stable polar high pressure systems.
(https://www.noaa.gov/jetstream/global/global-atmospheric-circulations)
Surface winds¶
#computing the temporal and longitudinal average wind components
u_wind= ds_uvslp.u10.mean(dim=['time', 'longitude'])
v_wind= ds_uvslp.v10.mean(dim=['time', 'longitude'])
#plotting on a line plot
u_wind.plot(label='temporal and zonal average of u wind component');
v_wind.plot(label='temporal and zonal average of v wind component')
plt.axhline(0, label= '0 horizontal wind line', color='red')
plt.legend(title='Wind speed [ms-1]')
plt.ylabel('ms-1')
plt.xlabel('latitude [°N]')
plt.title('temporal and zonal average wind speed at 10m, ERA5 1979-2018');
# easterlies: negative values
# westerlies: positive values
Similarly, explain the direction and strength of the zonal and meridional winds on earth (tip: the sea-level pressure plot helps)
The direction and strength of zonal and meridional winds are primarily determined by Earth's atmospheric circulation patterns, which are influenced by solar heating, the Coriolis effect, and the distribution of high and low-pressure systems. Zonal winds are winds that blow parallel to lines of latitude (u wind component), where positive number is a west wind and a negative number is an east wind. Pressure gradients and the corriolis effect are the drivers for those winds. Trade winds (0° - 30° N/S, headly cell) are easterlies, that are caused by descending air in the subtropical high pressure zone that flows towards the tropics and is directed eastward by the coriolis effect.
From 30°-60° N/S, ferrel cell, there are westerlies caused by polewards flowing air from the subtropical high pressure belt. The southern hemisphere has a lot more ocean cover, leading to higher wind speeds, because there are less barriers.
From 60°-90° N/S there is the polar easterlies, caused by cold polar air flowing to low pressure areas equator wards.
Meridional winds are the v wind component, positive for northward wind and negative for southward wind, driven by temperature and pressure differences between the equatorial, mid latitude and polar regions. In the headly cell (0°-30°N/S) the air is moving equatorwards at the surface because it is pulled in by the low pressure area in this region. In the ferrel cell (30°-60°N/S) air is moving polewards, where it rises up at the border between the ferrel cell and the polar cell. In the polar cell (60°-90°N/S) cold air is sinking at the polar highs and flows equatorwards at the surface.
(https://www.noaa.gov/jetstream/global/global-atmospheric-circulations)
4 Temperature change and CO2 concentrations¶
Monthly global CO2 concentration as a function of time¶
df
year | month | decimal | average | average_unc | trend | trend_unc | |
---|---|---|---|---|---|---|---|
date | |||||||
1979-01-01 | 1979 | 1 | 1979.042 | 336.56 | 0.11 | 335.92 | 0.10 |
1979-02-01 | 1979 | 2 | 1979.125 | 337.29 | 0.09 | 336.26 | 0.10 |
1979-03-01 | 1979 | 3 | 1979.208 | 337.88 | 0.11 | 336.51 | 0.10 |
1979-04-01 | 1979 | 4 | 1979.292 | 338.32 | 0.13 | 336.72 | 0.11 |
1979-05-01 | 1979 | 5 | 1979.375 | 338.26 | 0.04 | 336.71 | 0.11 |
... | ... | ... | ... | ... | ... | ... | ... |
2024-05-01 | 2024 | 5 | 2024.375 | 423.82 | 0.10 | 422.19 | 0.06 |
2024-06-01 | 2024 | 6 | 2024.458 | 423.11 | 0.10 | 422.54 | 0.06 |
2024-07-01 | 2024 | 7 | 2024.542 | 421.42 | 0.10 | 422.74 | 0.06 |
2024-08-01 | 2024 | 8 | 2024.625 | 419.99 | 0.10 | 422.85 | 0.06 |
2024-09-01 | 2024 | 9 | 2024.708 | 420.26 | 0.10 | 423.09 | 0.06 |
549 rows × 7 columns
print(df.head())
year month decimal average average_unc trend trend_unc date 1979-01-01 1979 1 1979.042 336.56 0.11 335.92 0.10 1979-02-01 1979 2 1979.125 337.29 0.09 336.26 0.10 1979-03-01 1979 3 1979.208 337.88 0.11 336.51 0.10 1979-04-01 1979 4 1979.292 338.32 0.13 336.72 0.11 1979-05-01 1979 5 1979.375 338.26 0.04 336.71 0.11
# plotting the monthly average concentration [average] against time
plt.plot(df.index, df['average'], color= 'black', label= 'Monthly average CO2 concentration')
plt.title('Monthly average CO2 concentration, NOAA 1979-2024')
plt.xlabel('Time')
plt.ylabel('CO2 concentration [ppm]');
Question: Describe and explain the annual cycle of CO2 concentrations:
The annual cycle of CO2 concentration is characterized by regular seasonal changes of CO2 concentration in the atmosphere (about 7 ppm flux per year), as can be seen on the diagram above. The reason for this change in concentration is the change in photosynthetic activity of terrestrial vegitation. Since the bulk of the landmasses are located in the northern hemisphere, the plant activity there is high during the northern summer. CO2 is absorbed, lowering the concentration. In winter, when northern hemisphere plant activity decreases, some of the stored CO2 is released back into the atmosphere.
(https://climate.nasa.gov/vital-signs/carbon-dioxide/?intent=121)
Annual average timeseries of global CO2 concentration as a function of time¶
Question: What was the CO2 concentration in the atmosphere in the pre-industrial era? Compute the annual increase in CO2 concentration (unit: ppm per year) between 1980 and 1985 and between 2016 and 2021.
# answer:
#slicing up the data between the years 1980-1985 and 2016-2021
df_1980_85= df.loc['1980':'1985']
df_2016_21= df.loc['2016':'2021']
#plotting the dataset from 1980-1985
plt.plot(df_1980_85.index, df_1980_85['average'], color= 'black', label= 'Monthly average CO2 concentration from 1980-1985')
plt.title('Monthly average CO2 concentration, NOAA 1980-1985')
plt.xlabel('Time')
plt.ylabel('CO2 concentration [ppm]');
# plotting the dataset from 2016 to 2021
plt.plot(df_2016_21.index, df_2016_21['average'], color= 'red', label= 'Monthly average CO2 concentration from 2016-2021')
plt.title('Monthly average CO2 concentration, NOAA 2016-2021')
plt.xlabel('Time')
plt.ylabel('CO2 concentration [ppm]');
# calculating the annual average time series
annual_avg= df['average'].resample('YE').mean()
# print(anual_avg)
plt.plot(annual_avg.index, annual_avg, color= 'black', label='Annual average CO2 concentration')
plt.title('Annual average CO2 concentration, NOAA 1979-2024')
plt.xlabel('Time')
plt.ylabel('CO2 concentration [ppm]');
Annual average timeseries of global CO2 concentration and of global 2m temperature¶
# using annual average CO2 time series
df_annual_avg_CO2= annual_avg
# reloading the dataset
ds_t2m= xr.open_dataset(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\ERA5_LowRes_Monthly_t2m.nc')
# calculate annual mean temperature
ds_t2m_annual= ds_t2m.t2m.resample(time='YE').mean()
# weighing dataset by latitude
weight = np.cos(np.deg2rad(ds_t2m.latitude))
# creates variable as cosphi of the latitude dataset
weight = weight / weight.sum()
# Apply the weight correctly and match dataset dimensions
weight = weight.broadcast_like(ds_t2m_annual)
# Apply weights and compute global average
weighted_t2m= (ds_t2m_annual*weight).sum(dim=['longitude','latitude'])/ weight.sum(dim=['latitude','longitude'])
# convert from K to °C
weighted_t2m= weighted_t2m -273.15
# defining ax1 for plotting
fig, ax1= plt.subplots()
#plotting the CO2 concentrations on one axis
ax1.plot(df_annual_avg_CO2.index, df_annual_avg_CO2, color= 'black', label='Annual average CO2 concentration [ppm], NOAA 1979-2024')
ax1.set_xlabel('Time')
ax1.set_ylabel('CO2 concentration [ppm]')
ax1.tick_params(axis='y', labelcolor='black')
ax1.grid(False)
# plotting the 2 meter temperature on the other y-axis
ax2=ax1.twinx()
ax2.plot(weighted_t2m['time'].values, weighted_t2m.values, color='red', label='Annual average 2m temperature [°C], ERA5 1979-2018')
ax2.set_xlabel('Time')
ax2.set_ylabel('°C')
ax2.tick_params(axis='y', labelcolor='red')
# Combine legends from both axes
lines1, labels1 = ax1.get_legend_handles_labels()
lines2, labels2 = ax2.get_legend_handles_labels()
# Create a single legend, placing both entries below each other
ax1.legend(lines1 + lines2, labels1 + labels2, loc='upper left')
plt.title('Annaual average atmospheric CO2 concentration and 2m temperature');
Question: Describe the relationship between global temperatures and CO2 concentrations. Beside CO2, name three processes that can influence temperature variability and change at the global scale.
When inspecting the diagram that compares mean annual temperature and atmospheric CO2 concentration, there seems to be a direct link of rising CO2 concentrations to rising average temperatures. The CO2 contentration line looks like a regression line for the rising temperature curve.
Other processes that can influence variability and change at the global scale are:
One process is the prenence of other greenhouse gases, most notably methane (CH4), which is present in the atmosphere in much lower quantities than CO2, but has high greenhouse effect. Thawing permafrost in Sibiria for example is beliefed to help the ground release stored methane in large quantities, thus further warming the climate (https://climate.mit.edu/explainers/permafrost).
Geological processes cannot be underestimated. One of them is plate tectonics. For one, high tectonic activity (for example high rates of ocean floor spreading) can potentially release a lot of gasses, changing the climate dramatically. The cretaceous period, which was one of the warmest periods ever in earth history is recorded to have very high ocean floor spreading rates.
Also the tectonically caused opening and closing of seaways can massively affect the global ocean circulation and disrupting heat circulation around the planet, even leading to extinction events in the geologic past.
(Rocky Austria, 2013, Verlage der Geologischen Bundesanstalt)
Open research question¶
My dashboard research question: Geography: Italy (2020-2100) Indicators: Risk of extremely hot years (probability of once in 10 years), Terrestrial climate Glaciers thinning rate, Glaciers
Research question¶
How will mean temperature change and the glacier thinning rate be affected by climate change from 2020 to 2100 in Italy? An analysis conducted on different scenarios.
Changes in mean temperature (3 scenarios)¶
Glacier thinning rate (3 scenarios)¶
Plotting the data¶
# Changes in mean temperature
df_mean_T_curpol= pd.read_csv(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\Mean_temperature\impact-time_ITA_curpol_terclim-mean-temperature_0.5_present-day.csv')
df_mean_T_1p5= pd.read_csv(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\Mean_temperature\impact-time_ITA_ref-1p5_terclim-mean-temperature_0.5_present-day.csv')
df_mean_T_delayed= pd.read_csv(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\Mean_temperature\impact-time_ITA_gs_terclim-mean-temperature_0.5_present-day.csv')
# Changes in glacier volume
df_glacier_thin_curpol = pd.read_csv(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\Glacier_thinning\impact-time_ITA_curpol_glacier-thinning_rate_0.5_present-day-2020 (1).csv')
df_glacier_thin_1p5= pd.read_csv(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\Glacier_thinning\impact-time_ITA_ref-1p5_glacier-thinning_rate_0.5_present-day-2020.csv')
df_glacier_thin_delayed= pd.read_csv(r'C:\Users\lorenz\OneDrive - uibk.ac.at\Erdwissenschaften\Kurse_7-Semester\Kurse\VU Klimasystem\Project\Data\Glacier_thinning\impact-time_ITA_gs_glacier-thinning_rate_0.5_present-day-2020.csv')
#df_ext_hot_2020_curpol
#df_glacier_thin_curpol
# merge the datasets (curpol)
curpol_data = pd.merge(df_mean_T_curpol[['year', 'terclim-mean-temperature_mean']],
df_glacier_thin_curpol[['year', 'glacier-thinning_rate_mean']],
on='year')
# merge the datasets (1p5 stabilisation)
stab_1p5_data= pd.merge(df_mean_T_1p5[['year', 'terclim-mean-temperature_mean']],
df_glacier_thin_1p5[['year', 'glacier-thinning_rate_mean']],
on='year')
# merge the datasets (delayed climate action)
delayed_data= pd.merge(df_mean_T_delayed[['year', 'terclim-mean-temperature_mean']],
df_glacier_thin_delayed[['year', 'glacier-thinning_rate_mean']],
on='year')
# plot the data (connection of the 3 scenarios and temperature change on glacial thinning rate)
plt.figure(figsize=(12,5))
#plot the 3 scenarios (curpol)
plt.plot(curpol_data['terclim-mean-temperature_mean'],
curpol_data['glacier-thinning_rate_mean'],
label= '2020 climate policies', color='blue',
marker='.')
# scenario stab at 1p5
plt.plot(stab_1p5_data['terclim-mean-temperature_mean'],
stab_1p5_data['glacier-thinning_rate_mean'],
label= 'Stabilisation at 1.5 °C', color= 'orange',
marker='x')
# scenario delayed climate action
plt.plot(stab_1p5_data['terclim-mean-temperature_mean'],
stab_1p5_data['glacier-thinning_rate_mean'],
label= 'Delayed climate action', color='red',
marker='.')
# Add labels, legends, and title
plt.xlabel('Change in mean temperature (°C)', fontsize=12)
plt.ylabel('Glacier thinning rate (m water equivalent/year)', fontsize=12)
plt.title('Correlation between change in mean temperature and the glacier thinning rate in Italy', fontsize=14)
plt.legend()
plt.grid(True)
plt.show()
#plot current policies data for temperature change (curpol)
plt.plot(curpol_data['year'],
curpol_data['terclim-mean-temperature_mean'],
label= '2020 current policies', color='blue',
marker='.')
#plot current policies data for temperature change (1p5)
plt.plot(stab_1p5_data['year'],
stab_1p5_data['terclim-mean-temperature_mean'],
label= 'Stabilisation at 1.5°C', color= 'orange',
marker='.')
#plot current policies data for temperature change (delayed)
plt.plot(delayed_data['year'],
delayed_data['terclim-mean-temperature_mean'],
label= 'delayed climate action', color= 'red',
marker='.')
# Add labels, legends, and title
plt.xlabel('Year', fontsize=12)
plt.ylabel('Mean temperature change (°C))', fontsize=12)
plt.title('Italy', fontsize=14)
plt.legend()
plt.grid(True)
plt.show();
#plot current policies data for glacier thinning rate (curpol)
plt.plot(curpol_data['year'],
curpol_data['glacier-thinning_rate_mean'],
label= '2020 current policies', color='blue',
marker='.')
#plot current policies data for glacier thinning rate (1p5)
plt.plot(stab_1p5_data['year'],
stab_1p5_data['glacier-thinning_rate_mean'],
label= 'Stabilisation at 1.5°C', color= 'orange',
marker='.')
#plot current policies data for glacier thinning rate (delayed)
plt.plot(delayed_data['year'],
delayed_data['glacier-thinning_rate_mean'],
label= 'delayed climate action', color= 'red',
marker='.')
# Add labels, legends, and title
plt.xlabel('Year', fontsize=12)
plt.ylabel('Glacier thinning rate (m water equivalent/year) )', fontsize=12)
plt.title('Italy', fontsize=14)
plt.legend()
plt.grid(False)
plt.show();
The shown plots show the connection of the rise of mean temperature changes and the glacial thinning rate of the country of Italy for the three selected scenarios (https://www.ipcc.ch/srocc/chapter/chapter-2/). The IPCC report assesses observed and projected changes in the cryosphere, also taking the European high alpine glaciers into consideration. The report highlights that glaciers in the European Alps have experienced significant mass loss due to rising temperatures. This trend is expected to continue, as can be seen in the data plots above with the 2020 current policies scenario being the one that would lead to the highest rate of glacier melting.
Guiding Questions¶
Question 1: How do the scenarios differ over time for each Indicator?
Question 2: What are the spatial differences between scenarios for each Indicator?
Question 3: Are there any correlations between your selected Indicators?
Question 1:
For the mean temperature change in Italy, the "current climate policie" scenario shows the most sharp rise in projected temperature, exceeding the 2°C warming mark by 2100. A linear rise in mean temperature can be determined. The scenario "Stabilisation at 1.5°C" describes a similar rise in temperatures until the mid 2030s, but then a sharp decline in temperature rise is noteable. No further increase is visible between 2035 and 2100, and it tops out at ca. 0.4°C warming as mean annual temperature. The scenario "delayed climate action" shows similar projections as the "Stabilisation at 1.5°C" scenario. The difference here is, that the temperature increase stops in about 2040 and tops out at 0.6°C.
For the glacier thinning rate indicator, it is noteable that all scenarios are estimating ever lower thinning rates from now to 2100. This is because large volumes of the glaciers have already deglaciated in the upcoming years, leaving less ice to melt in the future. The "current policies" scenario again sees the highest rate of glacier thinning, where "stabilisation at 1.5°C" and "delayed climate action" display significantly lower thinning rates ("stabilisation at 1.5°C has slightly lower thiining rates than "delayed climate policies"), reaching a thinning rate close to 0 by 2100. The 3 scenarios start to differ in their projections by the year 2035.
Question 2:
The spacial diffenernce between the scenarios is best described in the following figures, that compare the scenarios for the year 2100 on the map. For the glacier thinning rate, there are significant differences in certain areas (central northern Italy displays the highest thinning rate, with Northwestern and Northeastern Italy displaying lower rates). The map shows again, that the "current policies" scenario causes the highest thinning rate, followed by "stabilisation at 1.5°C" and "delayed climate action" scenarios.
For the mean temperature developmetn, we see that the different scenarios create different temperature rises throughout italy, however the spacial difference for each scenario is only minor to non existent, which means the changes that the scenarios describe affect all of Italy in the same way.
Question 3:
There is a correlation between the mean temperature change and the thinning rate of glaciers in Italy. The plot "Correlation between change in mean temperature and the glacier thinning rate in Italy" shows, that there is a higher thinning rate for glaciers with warmer mean temperatures than with colder mean temperatures.