Assignment: CMIP6 temperature projections#
# 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 cartopy # Map projections libary
import cartopy.crs as ccrs # Projections list
# Some defaults:
plt.rcParams['figure.figsize'] = (12, 5) # Default plot size
Global CMIP6 data#
Visit the data download page for CMIP6 data.
Download the “ultra low resolution” ERA5 temperature data from the link. This is the same data as you’ve used so far, but at an even lower resolution of 2°. I’ve coarsened the data even more to reduce the volume of climate projection data you’ll have to manipulate for this assignment.
Now download temperature data from the climate model of your choice (it doesn’t matter which one) and for the scenarios ssp126 and ssp585. I have prepared these data to make your life a bit easier. Most notably, I have resampled the data to be on the same grid as the ultra low resolution (2°) ERA5 data, which makes working with the data considerably easier. Normally, each ESM has their own resolution, ranging from 0.7° (for EC-Earth3) to 2.50° (for IPSL-CM6A-LR).
Historical reference data: ERA5#
Let me open the 2° ERA5 data for you and extract the 2m temperature data in °C. I’ll also select the 1979, 2015 period, and compute the annual averages as well as the time period average of this data. This should be familiar to you:
# Open the file
ds_era = xr.open_dataset('../data/ERA5_UltraLowRes_Monthly_t2m.nc')
# Select temperature for the given time period and convert to °C
t2m_era = ds_era.t2m.sel(time=slice('1979', '2015')) - 273.15
# Compute the annual average
t2m_era_annual_avg = t2m_era.resample(time='YS').mean()
# Compute the period average
t2m_era_avg = t2m_era.mean(dim='time')
Now let me also compute the globally averaged, annual mean temperature time series for you. Here again, this should hopefully be familiar to you as well:
# Meridional weights
weight = np.cos(np.deg2rad(t2m_era.latitude))
weight = weight / weight.sum()
# Meridionally weighted zonal mean - we did this before, but here I'm squeezing it into one single line
t2m_era_ats = (t2m_era_annual_avg.mean(dim='longitude') * weight).sum(dim='latitude')
Now make sure you understand what each of the variable above represents. This should be a repetition of what we’ve learned in the lessons so far, but it’s always good to make sure we are on the same page. In the markdown cell below, explain in your own words:
t2m_era
is … Its dimensions are …t2m_era_annual_avg
is … Its dimensions are …t2m_era_avg
is … Its dimensions are …t2m_era_ats
is … Its dimensions are …
# Explore the variables here to be sure
Historical CMIP6 data#
If any of what we’ve done above is too complex for you, you may pause, and go back to the previous lessons. You may also use the time in class to ask your questions!
Now, if your comfortable going forward, let’s go!
Averages and local and global ESM bias#
Now open the ssp126 ESM file you downloaded. Give it a recognizable name. Explore the file’s content.
# Open the file
Note that the temperature variable name has changed. Other than that, the file content should be familiar to you?
Now repeat the steps above, but with this ESM file, and renaming the variables accordingly. I suggest replacing era
with ssp126
for simplicity. Your goal should be to compute the following variables in a similar fashion as you did for ERA5:
t2m_ssp126
t2m_ssp126_annual_avg
t2m_ssp126_avg
t2m_ssp126_ats
# Your answer here
Great!
Now let’s get started with the interesting stuff. Start by computing the period average of the global average temperature for each dataset. This should be one single, scalar value: the global temperature according to ERA5, and according to the ESM you downloaded. Compare the two values.
# Your answer here
Now plot a world map of the period average temperature (t2m_era_avg
and t2m_ssp126_avg
) using the same colorscale values. Plot a third map: the difference between the two.
# Your answer here
The map “ESM minus ERA5” is called the “average temperature bias” of the ESM you chose. Look it up online if you don’t know what I am talking about when I mention “bias”.
Now write down your answer to the following questions:
If the climate model would be perfect, would we expect any difference between ERA5 and the climate model? Why?
Are the differences always positive, or always negative? Why?
Where are the largest differences to be seen, i.e. in which regions. Can you detect a pattern, or at least formulate hypotheses as to why these regions show such differences?
# Your answer here
Interannual variability#
Now plot the two annual timeseries together on the same line plot (t2m_era_ats
and t2m_ssp126_ats
). Make the plot nice: add a legend, a y-axis label, and a title.
# Your answer here
Interpret what you see, and try to answer the following questions:
If the ESM you downloaded has a bias. Is this bias “systematic” (i.e. similar over the same time period), or random?
Do the ESM and ERA5 display similar trends (qualitatively)?
If any given year is warmer/colder than usual in the ERA5 timeseries, is it also the case in the ESM? Or, in other worlds, are the two timeseries correlated?
Do we expect the two timeseries to correlate, or not? Why?
# Your answer here
The (likely) bias between a given ESM realisation and “observations” (here, ERA5) is a very well documented problem in climate science. The existence of this bias means that scientist have developped specific strategies to deal with this problem. One strategy is called bias correction, and there exists entire textbooks on the subject. We will get to this later.
Another strategy is to assume that despite having a bias, the ESM can still be considered skilfull at representing slow changes in the climate system. I.e., even if the average climate is a bit off at any given time, the difference between two periods (i.e. the climate change signal) might still be skilfull and provide useful information.
Now let’s test this hypothesis. For each timeseries, (t2m_era_ats
and t2m_ssp126_ats
), compute the average of the first decade, and subtract it from the timeseries. Create two new timeseries from this operation, called delta_t2m_era_ats
and delta_t2m_ssp126_ats
. Plot them.
Tip: a good way to check if you’ve done this correctly is to check your plot: the first years should vary around the 0°C line.
# Your answer here
Now (qualitatively) test the hypothesis that your ESM is skillful at representing the global warming trend (or not). Discuss.
# Your answer here
CMIP6 projections#
Now that we’ve tested the past, let’s have a first look at the global projections. We can put ERA5 aside, and focus on the two scenarios we’ve downloaded: ssp126 and ssp585. The exercises below are independant from the above, but you’ll find it much easier if you have done the above first!
Tip: the commands you’ll have to run below are extremely similar to the above: they only differ by the time periods considered!
Open the two ESM files (I suggest to name each dataset ds_ssp126
and ds_ssp585
). Compute the following variables for each SSP:
t2m_ssp126_annual_avg
: the annual averages of the ESM temperatures in °Ct2m_ssp126_avg_historical
: the time average of t2m_ssp126_annual_avg for 1985-2014t2m_ssp126_avg_2100
: the time average of t2m_ssp126_annual_avg for 2070-2099delta_t2m_ssp126_ats
: the annual global average timeseries of temperature change with respect to 1985-20154
# Your answer here
Plot delta_t2m_ssp126_ats
and delta_t2m_ssp585_ats
on the same plot. Answer the following questions:
When are the two timeseries identical, and when do they start to vary from another? Can you figure out why?
What is the (approximate) temperature change at the end of the century for each scenario?
# Your answer here
Is there any difference between t2m_ssp585_avg_historical
and t2m_ssp126_avg_historical
? hint: there should be none. Again: can you figure out why?.
# Your answer here
Finally, now plot the climate change map (2100 minus historical) for both scenarios, with the same colorbars. Interpret what you see.
# Your answer here
Optional : more analyses#
From there, I’m sure you can envision for yourself the number of (in my opinion) interesting analyses you could do with very little modifications to the code above! On the top of my mind:
download another ESM, and see if the results are similar
repeat the timeseries analysis for a specific region, or a city or place. You know how to select a specific location already! What is the expected warming in Bristol, for example?
download more SSPs, and check the differences.
Doing any of the above will help you to train all the skills you’ve learned recently. They are a very good way to spend some time exercising!
# Your answer here
Optional: precipitation in ERA5#
The assignment below is a nice way to train the plotting skills learned in the previous lesson. It should be relatively quick to do, and you can do it at your own pace.
Download the ERA5_LowRes_Monthly_tp
precipitation file.
Open the file with xarray and explore it. The units of monthly precipitation are wrongly labeled (unfortunately). They should read: m per day.
ds = xr.open_dataset('../data/ERA5_LowRes_Monthly_tp.nc')
ds.tp
<xarray.DataArray 'tp' (time: 552, latitude: 241, longitude: 480)> Size: 255MB [63855360 values with dtype=float32] Coordinates: * time (time) datetime64[ns] 4kB 1979-01-01T06:00:00 ... 2024-12-01T0... * latitude (latitude) float64 2kB 90.0 89.25 88.5 ... -88.5 -89.25 -90.0 * longitude (longitude) float64 4kB -179.6 -178.9 -178.1 ... 178.9 179.6 Attributes: long_name: Total precipitation units: m standard_name: unknown
Compute the average total annual precipitation (average precipitation over a year, in mm yr\(^{-1}\)) and store it in a variable called “annual_prcp”. Plot it.
# Your answer here
Draw a new plot of “annual_prcp”, this time with a new colormap (‘YlGnBu’) and with the following discrete levels specified: [50, 200, 500, 700, 1000, 1500, 2000, 3000, 5000]. Now have a look at the patterns again.
Where does it fall more than 3000 mm precipitation a year? Less than 50 mm precipitation a year? Note that it could be possible to use the “.where()” function (not taught yet) to highlight these areas easily. Bonus: can you come up with a plot showing these areas on the map?
# Your answer here
Plot the average precipitation in January on a map. Do the same with precipitation in July, and choose the same levels for both maps in order to compare them. Discuss the patterns that you see.
# Your answer here