Open In Colab   Open in Kaggle

Tutorial 4: Reconstructing Past Changes in Atmospheric Climate#

Week 1, Day 4, Paleoclimate

Content creators: Sloane Garelick

Content reviewers: Yosmely Bermúdez, Dionessa Biton, Katrina Dobson, Maria Gonzalez, Will Gregory, Nahid Hasan, Sherry Mi, Beatriz Cosenza Muralles, Brodie Pearson, Jenna Pearson, Chi Zhang, Ohad Zivan

Content editors: Yosmely Bermúdez, Zahra Khodakaramimaghsoud, Jenna Pearson, Agustina Pesce, Chi Zhang, Ohad Zivan

Production editors: Wesley Banfield, Jenna Pearson, Chi Zhang, Ohad Zivan

Our 2023 Sponsors: NASA TOPS and Google DeepMind

Tutorial Objectives#

In this tutorial, we’ll analyze δD and atmospheric CO2 data from the EPICA Dome C ice core. Recall from the video that δD and δ18O measurements on ice cores record past changes in temperature, and that measurements of CO2 trapped in ice cores can be used to reconstruction past changes in Earth’s atmospheric composition.

By the end of this tutorial you will be able to:

  • Plot δD and CO2 records from the EPICA Dome C ice core

  • Assess changes in temperature and atmospheric greenhouse gas concentration over the past 800,000 years

Setup#

# installations ( uncomment and run this cell ONLY when using google colab or kaggle )

# !pip install pyleoclim
# !pip install cartopy
# imports
import pandas as pd
import pooch
import os
import tempfile
import pyleoclim as pyleo
# @title Helper functions

def pooch_load(filelocation=None, filename=None, processor=None):
    shared_location = "/home/jovyan/shared/Data/tutorials/W1D4_Paleoclimate"  # this is different for each day
    user_temp_cache = tempfile.gettempdir()

    if os.path.exists(os.path.join(shared_location, filename)):
        file = os.path.join(shared_location, filename)
    else:
        file = pooch.retrieve(
            filelocation,
            known_hash=None,
            fname=os.path.join(user_temp_cache, filename),
            processor=processor,
        )

    return file
# @title Video 1: Atmospheric Climate Proxies

from ipywidgets import widgets
from IPython.display import YouTubeVideo
from IPython.display import IFrame
from IPython.display import display


class PlayVideo(IFrame):
  def __init__(self, id, source, page=1, width=400, height=300, **kwargs):
    self.id = id
    if source == 'Bilibili':
      src = f'https://player.bilibili.com/player.html?bvid={id}&page={page}'
    elif source == 'Osf':
      src = f'https://mfr.ca-1.osf.io/render?url=https://osf.io/download/{id}/?direct%26mode=render'
    super(PlayVideo, self).__init__(src, width, height, **kwargs)


def display_videos(video_ids, W=400, H=300, fs=1):
  tab_contents = []
  for i, video_id in enumerate(video_ids):
    out = widgets.Output()
    with out:
      if video_ids[i][0] == 'Youtube':
        video = YouTubeVideo(id=video_ids[i][1], width=W,
                             height=H, fs=fs, rel=0)
        print(f'Video available at https://youtube.com/watch?v={video.id}')
      else:
        video = PlayVideo(id=video_ids[i][1], source=video_ids[i][0], width=W,
                          height=H, fs=fs, autoplay=False)
        if video_ids[i][0] == 'Bilibili':
          print(f'Video available at https://www.bilibili.com/video/{video.id}')
        elif video_ids[i][0] == 'Osf':
          print(f'Video available at https://osf.io/{video.id}')
      display(video)
    tab_contents.append(out)
  return tab_contents


video_ids = [('Youtube', 'y5zom-8iKv4'), ('Bilibili', 'BV1Uh4y1Z7dg')]
tab_contents = display_videos(video_ids, W=730, H=410)
tabs = widgets.Tab()
tabs.children = tab_contents
for i in range(len(tab_contents)):
  tabs.set_title(i, video_ids[i][0])
display(tabs)

Section 1: Exploring past variations in atmospheric CO2#

As we learned in the video, paleoclimatologists can reconstruct past changes in atmospheric composition by measuring gases trapped in layers of ice from ice cores retrieved from polar regions and high elevation mountain glaciers. We’ll specifically be focusing on paleoclimate records produced from the EPICA Dome C ice core from Antarctica.

Credit: Conway et al 2015, Nature Communications

Let’s start by downloading the data for the composite CO2 record for EPICA Dome C in Antarctica:

# donwload the data using the url
filename_antarctica2015 = "antarctica2015co2composite.txt"
url_antarctica2015 = "https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/antarctica2015co2composite.txt"

data_path = pooch_load(
    filelocation=url_antarctica2015, filename=filename_antarctica2015
)  # open the file

co2df = pd.read_csv(data_path, skiprows=137, sep="\t")

co2df.head()
age_gas_calBP co2_ppm co2_1s_ppm
0 -51.03 368.02 0.06
1 -48.00 361.78 0.37
2 -46.28 359.65 0.10
3 -44.41 357.11 0.16
4 -43.08 353.95 0.04

Next, we can store this data as a Series in Pyleoclim:

ts_co2 = pyleo.Series(
    time=co2df["age_gas_calBP"] / 1000,
    value=co2df["co2_ppm"],
    time_name="Age",
    time_unit="kyr BP",
    value_name=r"$CO_2$",
    value_unit="ppm",
    label="EPICA Dome C CO2",
)
Time axis values sorted in ascending order

We can now plot age vs. CO2 from EPICA Dome C:

ts_co2.plot(color="C1")
(<Figure size 1000x400 with 1 Axes>,
 <Axes: xlabel='Age [ka]', ylabel='$CO_2$ [ppm]'>)
../../../_images/W1D4_Tutorial4_14_1.png

Notice that the x-axis is plotted with present-day (0 kyr) on the left and the past (800 kyr) on the right. This is a common practice when plotting paleoclimate time series data.

These changes in CO2 are tracking glacial-interglacial cycles (Ice Ages) over the past 800,000 years. Recall that these Ice Ages occur as a result of changes in the orbital cycles of Earth: eccentricity (100,000 year cycle), obliquity (40,000 year cycle) and precession (21,000 year cycle). Can you observe them in the graph above?

Section 2: Exploring the relationship between δD and atmospheric CO2#

To investigate the relationship between glacial cycles, atmospheric CO2 and temperature, we can compare CO2 to a record of hydrogen isotopic values (δD) of ice cores, which is a proxy for temperature in this case. Remember, when interpreting isotopic measurements of ice cores, a more depleted δD value indicates cooler temperatures, and a more enriched δD value indicates warmer temperatures. This is the opposite relationship we have looked at previously with δ18O, not because we are looking at a different isotope, but because we are not looking at the isotopic composition of ice rather than the isotopic composition of the ocean.

Let’s download the EPICA Dome C δD data, store it as a Series, and plot the data:

# donwload the data using the url
filename_edc3deuttemp2007 = "edc3deuttemp2007.txt"
url_edc3deuttemp2007 = "https://www.ncei.noaa.gov/pub/data/paleo/icecore/antarctica/epica_domec/edc3deuttemp2007.txt"
data_path = pooch_load(
    filelocation=url_edc3deuttemp2007, filename=filename_edc3deuttemp2007
)  # open the file

dDdf = pd.read_csv(data_path, skiprows=91, encoding="unicode_escape", sep="\s+")
# remove nan values
dDdf.dropna(inplace=True)

dDdf.head()
Bag ztop Age Deuterium Temperature
12 13 6.60 38.37379 -390.9 0.88
13 14 7.15 46.81203 -385.1 1.84
14 15 7.70 55.05624 -377.8 3.04
15 16 8.25 64.41511 -394.1 0.35
16 17 8.80 73.15077 -398.7 -0.42
dDts = pyleo.Series(
    time=dDdf["Age"] / 1000,
    value=dDdf["Deuterium"],
    time_name="Age",
    time_unit="kyr BP",
    value_name=r"$\delta D$",
    value_unit="\u2030",
    label=r"EPICA Dome C $\delta D$",
)
Time axis values sorted in ascending order
dDts.plot()
(<Figure size 1000x400 with 1 Axes>,
 <Axes: xlabel='Age [ka]', ylabel='$\\delta D$ [‰]'>)
../../../_images/W1D4_Tutorial4_20_1.png

When we observe the δD data, we see very similar patterns as in the atmospheric CO2 data. To more easily compare the two records, we can plot the two series side by side by putting them into a MultipleSeries object. Since the δD and CO2 values have different units, we can first standardize the series and then plot the data.

# combine series
ms = pyleo.MultipleSeries([dDts, ts_co2])

# standarize series and plot
ms.standardize().plot()
(<Figure size 1000x400 with 1 Axes>, <Axes: xlabel='Age [ka]', ylabel='value'>)
../../../_images/W1D4_Tutorial4_22_1.png

Now we can more easily compare the timing and magnitude of changes in CO2 and δD at EPICA Dome C over the past 800,000 years. During glacial periods, δD was more depleted (cooler temperatures) and atmospheric CO2 was lower. During interglacial periods, δD was more enriched (warmer temperatures) and atmospheric CO2 was higher.

Questions 2: Climate Connection#

  1. Why do δD, CO2 and glacial cycles covary so closely?

  2. Can you identify glacial and interglacial periods? Today, are we in an interglacial or glacial period?

  3. Do the cooling and warming periods of the cycles happen at the same rate?

  4. What climate forcings do you think are driving these cycles?

Summary#

In this tutorial, we dove into the captivating world of paleoclimatology, focusing on the analysis of hydrogen isotopes (δD) and atmospheric CO2 data from the EPICA Dome C ice core. This involved understanding how δD and δ18O measurements from ice cores can enlighten us about past temperature changes, and how trapped CO2 in these ice cores can help us reconstruct shifts in Earth’s atmospheric composition.

By the end of the tutorial, you should be comfortable with plotting δD and CO2 records from the EPICA Dome C ice core and assessing changes in temperature and atmospheric greenhouse gas concentrations over the past 800,000 years. In the next tutorial, we’ll introduce various paleoclimate data analysis tools.

Resources#

Code for this tutorial is based on an existing notebook from LinkedEarth that explores EPICA Dome C paleoclimate records.

Data from the following sources are used in this tutorial: