Exploring Ice sheet Gravimetric Mass Balance data, available through the C3S Climate Data Store#
About#
This tutorial will demonstrate how to plot the Gravimetric Mass Balance (GMB) data for selected regions across the Greenland or Antarctic ice sheets, using data from the Copernicus Climate Change Service (C3S). Gravimetric Mass Balance refers to the changes in the mass of ice sheets determined from satellite gravimetry, which measures variations in the Earth’s gravity field due to ice mass changes. These data are crucial for understanding how ice sheets contribute to sea level rise.
The GMB data provides estimates of ice mass loss or gain over time, derived from satellite-based gravimetric measurements from the GRACE and GRACE-FO satellites. These measurements track changes in the gravitational field caused by shifts in mass, such as the movement or melting of ice. The GMB data allows researchers to monitor long-term trends in ice sheet dynamics and their contribution to global sea level changes.
It will show you how to download data from the C3S Climate Data Store (CDS), calculate average change rates over a selectable period, and display the results.
Data Description:#
Source: Copernicus Climate Change Service (C3S) Climate Data Store (CDS)
Data Type: Satellite-based gravimetric measurements
Coverage: Greenland and Antarctic ice sheets
Variables: Time series of mass balance changes over specific regions with basin numbers
Format: NetCDF4 files
Prerequisites and data acquisition#
This tutorial is in the form of a Jupyter notebook. It can be run on a cloud environment, or on your own computer. You will not need to install any software for the training as there are a number of free cloud-based services to create, edit, run and export Jupyter notebooks such as this. Here are some suggestions (simply click on one of the links below to run the notebook):
Run the tutorial via free cloud platforms: |
|
|
---|
We are using cdsapi
to download the data. This package is not yet included by default on most cloud platforms. You can use pip
to install it. We use an exclamation mark to pass the command to the shell (not to the Python interpreter).
!pip install -q cdsapi
Import libraries#
The data is stored in netCDF4 files. To work with them, several libraries are needed. These are used to retrieve the data, unpack it, run calculations and plot the results.
# CDS API
import cdsapi
# File handling
import shutil
import glob
import os
# Calculations
import numpy as np
import xarray as xr
# Mapping
import cartopy.crs as ccrs
import cartopy.feature as cfeature
# Plotting
import matplotlib.pyplot as plt
Download data using CDS API#
This section is provides all necessary settings and input data to successfully run the use cases, and produce the figures.
Set up CDS API credentials#
We will request data from the Climate Data Store (CDS). In case you don’t have an account yet, please click on “Login/register” at the right top and select “Create new account”. With the process finished you are able to login to the CDS and can search for your preferred data.
We will request data from the CDS programmatically with the help of the CDS API.
First, we need to manually set the CDS API credentials.
To do so, we need to define two variables: URL and KEY.
To obtain these, first login to the CDS, then visit https://cds.climate.copernicus.eu/api-how-to and copy the string of characters listed after “key:”. Replace the #########
below with this string.
URL = 'https://cds.climate.copernicus.eu/api'
KEY = '############'
Search for data#
Select the ice sheet of interest and retrieve the dataset. An example of how to retrieve the data is given on the CDS, under ‘Show API request’ on the dataset’s webpage at https://cds.climate.copernicus.eu/datasets/satellite-ice-sheet-mass-balance?tab=download
The dataset comes in a zip file, and may include several files. Only the most recent is necessary - this contains all of the data in previous files, plus the latest update.
# Set ice_sheet to the desired ice sheet, either 'AntIS' or 'GrIS'
# This will be used to select data, and later to set up plot defaults
#ice_sheet = 'AntIS' #
ice_sheet = 'GrIS' #
# Download data from the CDS
c = cdsapi.Client(
# url=URL, key=KEY,
)
c.retrieve(
'satellite-ice-sheet-mass-balance',
{
'variable': 'all',
'format': 'zip',
},
'download.zip')
# Unpack the zip file and remove the zipped data
shutil.unpack_archive('download.zip', '.')
os.remove('download.zip')
# # List the files contained and select the latest netCDF (.nc) file. Print its filename
list_of_files = glob.glob('*.nc') # * means all if need specific format then *.nc
latest_file = max(list_of_files, key=os.path.getctime)
print('In the following you are seeing the data from: \n'+latest_file)
2024-12-17 13:56:40,302 INFO [2024-09-28T00:00:00] **Welcome to the New Climate Data Store (CDS)!** This new system is in its early days of full operations and still undergoing enhancements and fine tuning. Some disruptions are to be expected. Your
[feedback](https://jira.ecmwf.int/plugins/servlet/desk/portal/1/create/202) is key to improve the user experience on the new CDS for the benefit of everyone. Thank you.
2024-12-17 13:56:40,303 INFO [2024-09-26T00:00:00] Watch our [Forum](https://forum.ecmwf.int/) for Announcements, news and other discussed topics.
2024-12-17 13:56:40,304 INFO [2024-09-16T00:00:00] Remember that you need to have an ECMWF account to use the new CDS. **Your old CDS credentials will not work in new CDS!**
2024-12-17 13:56:40,304 WARNING [2024-06-16T00:00:00] CDS API syntax is changed and some keys or parameter names may have also changed. To avoid requests failing, please use the "Show API request code" tool on the dataset Download Form to check you are using the correct syntax for your API request.
2024-12-17 13:56:41,245 INFO Request ID is 532a4d76-7b24-443c-9284-64924f9926d2
2024-12-17 13:56:41,315 INFO status has been updated to accepted
2024-12-17 13:56:46,371 INFO status has been updated to running
2024-12-17 13:56:55,101 INFO status has been updated to successful
In the following you are seeing the data from:
C3S_GMB_GRACE_vers4.nc
Explore the data#
Open the data file and list its contents. These include descriptive comments.
# Open the NetCDF file wih xarray and print the dataset
ds = xr.open_dataset(latest_file)
ds
<xarray.Dataset> Size: 14MB Dimensions: (t: 216, AntB: 901322, N: 3, GrisB: 272965) Dimensions without coordinates: t, AntB, N, GrisB Data variables: (12/81) time (t) datetime64[ns] 2kB ... AntBasin (AntB, N) float32 11MB ... GrISBasin (GrisB, N) float32 3MB ... GrIS_total (t) float32 864B ... GrIS_total_er (t) float32 864B ... GrIS_1 (t) float32 864B ... ... ... East_AntIS_total (t) float32 864B ... East_AntIS_total_er (t) float32 864B ... West_AntIS_total (t) float32 864B ... West_AntIS_total_er (t) float32 864B ... AntIS_total (t) float32 864B ... AntIS_total_er (t) float32 864B ... Attributes: Title: GMB for Greenland and Antarctica ice sheets from th... institution: DTU Space - Geodesy and Earth Observations reference: Baratta et al. (2016), Groh and Horwart (2016) file_creation_date: Tue May 16 09:49:32 2023 region: Greenland and Antarctica missions_used: GRACE and and GRACE-FO time_coverage_start: Apr-2002 time_coverage_end: Dec-2022 Tracking_id: ab2360a4-82d5-42f3-babb-90ce976a8a8e netCDF_version: NETCDF4 product_version: 4.0 Summary: This data set is prepared for the C3S project, and ...
Plot the drainage basins#
Here the user can get an overview of the drainage basins available for the chosen Ice Sheet
# Load data
time_in_hours = ds['time']
time_in_hours_array = time_in_hours.values
if 'GrIS' in ice_sheet:
drainage_basin = ds['GrISBasin']
basin_range = range(1, 9) # For GrIS: 1 to 8
cmap = plt.colormaps['jet']
elif 'AntIS' in ice_sheet:
drainage_basin = ds['AntBasin']
basin_range = range(1, 28) # For AntIS: 1 to 27
cmap = plt.colormaps['jet']
# Create a figure and axis with a specific projection
fig = plt.figure(figsize=(12, 5))
if 'GrIS' in ice_sheet:
ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(-45, 71))
ext = [-60, -25, 57, 84]
elif 'AntIS' in ice_sheet:
ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(0, -90))
ext = [-180, 180, -90, -60]
ax1.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=0.5)
ax1.set_extent(ext, crs=ccrs.PlateCarree())
ax1.add_feature(cfeature.LAND, facecolor='white')
ax1.add_feature(cfeature.OCEAN, facecolor='gray')
# Add latitude and longitude gridlines
gl = ax1.gridlines(draw_labels=True, linewidth=0.5, color='gray', alpha=0.5, linestyle='--')
gl.top_labels = False
gl.xlabels_top = False
gl.xlabels_bottom = True
gl.ylabels_left = True
gl.ylabels_right = False
gl.xlabel_style = {'size': 10}
gl.ylabel_style = {'size': 10}
# Generate colors from colormap
colors = cmap(np.linspace(0, 1, len(basin_range))) # Get N distinct colors for the number of basins
for i, basin_num in enumerate(basin_range):
# Filter data for the specific basin
filtered_basins = drainage_basin.where((drainage_basin[:, 2] - basin_num).astype(int) == 0, drop=True)
basin_numbers_str = filtered_basins[:, 2].astype(str)
filtered_basins_2x = filtered_basins.where(basin_numbers_str.str.startswith(str(basin_num)+'.'), drop=True)
# Extract latitude, longitude, and basin number
lat, lon, basin_number = filtered_basins_2x[:,0].values, filtered_basins_2x[:,1].values, filtered_basins_2x[:,2].values
# Sort coordinates by longitude
sorted_indices = np.argsort(lon)
lon_sorted = lon[sorted_indices]
lat_sorted = lat[sorted_indices]
# Plot the sorted coordinates
ax1.plot(lon_sorted, lat_sorted, color=colors[i], linestyle='dashed', transform=ccrs.PlateCarree())
# Calculate the midpoint
midpoint_lat = np.mean(lat)
midpoint_lon = np.mean(lon)
# Add text to the middle of the lat-lon set
ax1.text(midpoint_lon, midpoint_lat, str(basin_num), color='white', transform=ccrs.PlateCarree(), fontsize=10, fontweight='bold')
plt.show()
![../_images/bc451edda2fc2daeb426ea642a7d68d1d66481c6e4768b27c2ee50677a4c774f.png](../_images/bc451edda2fc2daeb426ea642a7d68d1d66481c6e4768b27c2ee50677a4c774f.png)
Plot a time-series for a selcted drainage basin#
Here the data from the selected ice sheet is loaded based on the choosen basin number from above. The variables needed for the plotting below are also extracted here .
# Select the basin number:
basin_num = 7 # if set 0, then mass loss for all is shown. For GrIS 0-8, for AntIS 0-27 basins
# Load data
time_in_hours = ds['time']
if 'GrIS' in ice_sheet:
drainage_basin = ds['GrISBasin']
if 'AntIS' in ice_sheet:
drainage_basin = ds['AntBasin']
if basin_num != 0:
filtered_basins = drainage_basin.where((drainage_basin[:, 2] - basin_num).astype(int) == 0, drop=True)
basin_numbers_str = filtered_basins[:, 2].astype(str)
filtered_basins_2x = filtered_basins.where(basin_numbers_str.str.startswith(str(basin_num)+'.'), drop=True)
# Extracting latitude, longitude, and basin number
lat, lon, basin_number = filtered_basins_2x[:,0].values,filtered_basins_2x[:,1].values,filtered_basins_2x[:,2].values
gmb = ds[str(ice_sheet)+'_'+str(round(basin_num))]
gmb_er = ds[str(ice_sheet)+'_'+str(round(basin_num))+'_er']
else:
lat, lon = drainage_basin[:,0].values,drainage_basin[:,1].values
gmb = ds[str(ice_sheet)+'_total']
gmb_er = ds[str(ice_sheet)+'_total_er']
Set up the plot#
In this plot, we focus on displaying the specific basin area within the selected ice sheet. Each basin represents a predefined region, and its boundary is essential for understanding localized processes such as ice mass changes or environmental conditions. The boundary of the basin is highlighted on the geographical map. This serves as a spatial reference for understanding which part of the ice sheet is being analyzed in the accompanying time series graph.
Key Components:#
Basin Area Map: The geographical map shows the specific basin number selected for analysis. It helps orient the user by providing a visual representation of the area under consideration within the larger ice sheet. This is useful for understanding the spatial context of the following analysis.
Time Series Graph: Next to the basin map, a graph is displayed that tracks the mass change over time within the selected basin. This graph is where the data is visualized, providing insights into whether the basin has been gaining or losing ice mass over time. The combination of the basin map and time series graph allows us to interpret the temporal changes in mass for a specific region of the ice sheet.
# Create a figure and axis with a specific projection
fig = plt.figure(figsize=(12, 5))
# Create the first subplot with a projection
if 'GrIS' in ice_sheet:
ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(-45, 71))
ext = [-60, -25, 57, 84]
elif 'AntIS' in ice_sheet:
ax1 = fig.add_subplot(1, 2, 1, projection=ccrs.Orthographic(0, -90))
ext = [-180, 180, -90, -60]
ax1.add_feature(cfeature.COASTLINE.with_scale('10m'), linewidth=0.5)
ax1.set_extent(ext, crs=ccrs.PlateCarree())
ax1.add_feature(cfeature.LAND, facecolor='white')
ax1.add_feature(cfeature.OCEAN, facecolor='gray')
# Add latitude and longitude gridlines
gl = ax1.gridlines(draw_labels=True, linewidth=0.5, color='gray', alpha=0.5, linestyle='--')
# Remove latitude labels at the top
gl.top_labels = False
# Set the label spacing to display labels only once on either side
gl.xlabels_top = False
gl.xlabels_bottom = True
gl.ylabels_left = True
gl.ylabels_right = False
gl.xlabel_style = {'size': 10}
gl.ylabel_style = {'size': 10}
# Sort coordinates by longitude
sorted_indices = np.argsort(lon)
lon_sorted = lon[sorted_indices]
lat_sorted = lat[sorted_indices]
# Plot the sorted coordinates
ax1.plot(lon_sorted, lat_sorted, 'r', linestyle='dashed', transform=ccrs.PlateCarree())
ax1.fill(lon_sorted, lat_sorted, color='red', transform=ccrs.PlateCarree())
# Calculate the midpoint
midpoint_lat = np.mean(lat)
midpoint_lon = np.mean(lon)
# Add text to the middle of the lat-lon set
if basin_num != 0:
ax1.text(midpoint_lon-1, midpoint_lat, str(basin_num), color='white', transform=ccrs.PlateCarree())
else:
ax1.text(midpoint_lon-1, midpoint_lat, 'All', color='white', transform=ccrs.PlateCarree())
ax1.add_feature(cfeature.LAND, facecolor='red')
# Create the second subplot for time series
ax2 = fig.add_subplot(1, 2, 2)
ax2.plot(time_in_hours, gmb, '-', color='grey', label='Mass change')
ax2.fill_between(time_in_hours, gmb - gmb_er, gmb + gmb_er, alpha=0.3, color='grey', label='Error')
ax2.set_xlabel('Time')
ax2.set_ylabel('Mass change [GT]')
# Set the figure size
fig.set_size_inches((12, 5))
# Display the plot
plt.show()
![../_images/c762f99e84db98222b58d2c4328aa3f157083e730a62f4712f0ce3753fe2870b.png](../_images/c762f99e84db98222b58d2c4328aa3f157083e730a62f4712f0ce3753fe2870b.png)
Figure 1: Overview of mass change for the selected ice sheet basin. The left subplot shows a geographical map of the selected basin (or the entire ice sheet if basin_num
is 0), highlighting the basin’s boundary in red. The right subplot presents the time series of mass change for the basin, with the mass change values shown as a line plot and the associated uncertainties represented by shaded error bands. The map provides spatial context for the temporal changes observed in the time series plot.
Key Take-Home Points#
Understanding Ice Sheet Dynamics:
The Gravimetric Mass Balance (GMB) data from the Copernicus Climate Change Service (C3S) provides valuable insights into the changes in ice mass across the Greenland and Antarctic ice sheets. By analyzing these data, researchers can monitor how ice sheets contribute to sea level rise and assess long-term trends in ice mass loss or gain.Data Visualization:
The combination of a geographical basin map and a time series graph is crucial for a comprehensive analysis. The basin map offers a spatial reference, showing the specific region of the ice sheet under investigation. The time series graph, on the other hand, illustrates the temporal changes in ice mass within that basin, providing clear insights into whether the basin is gaining or losing ice mass over time.Importance of Basin Selection:
Selecting a specific basin for analysis allows for a focused study of localized ice mass changes. Understanding these localized processes is essential for detailed assessments of ice sheet dynamics and their impact on global sea level changes.Data Access and Preparation:
Accessing and preparing GMB data from the C3S Climate Data Store requires registration and setting up the CDS API. It is essential to follow these steps to ensure successful data retrieval and compliance with dataset terms of use.Tools and Libraries:
Working with netCDF4 files requires specific libraries for data retrieval, unpacking, calculation, and plotting. Ensuring that these libraries are properly set up is crucial for efficient and accurate analysis.
By integrating these elements, you can effectively analyze and interpret the gravimetric mass balance data, gaining insights into ice sheet changes and their broader implications.