How much ice has Greenland or Antarctica lost?
Draw a rectangle, then check which collections cover it. Most NASA data is global, so a big box matches a lot.
-50, 60 → -20, 80 (Greenland ice sheet (central))An ice sheet is a continent-sized slab of frozen freshwater. When it loses ice, that water ends up in the ocean and raises sea level everywhere. The clever part is that you don't have to weigh the ice directly. A pair of satellites can measure how much an ice sheet weighs from orbit by sensing its gravity. More ice means a stronger gravitational tug. As the ice melts, the tug weakens, and that tiny change is the mass it lost.
How much ice has Greenland or Antarctica lost?
An ice sheet is a continent-sized slab of frozen freshwater. When it loses ice, that water ends up in the ocean and raises sea level everywhere. The clever part is that you don’t have to weigh the ice directly. A pair of satellites can measure how much an ice sheet weighs from orbit by sensing its gravity. More ice means a stronger gravitational tug. As the ice melts, the tug weakens, and that tiny change is the mass it lost.
Which data to use, and how
Use this dataset: GRACE-FO mascons (short name GRACEFO_L3_JPL_RL06.X_M). GRACE-FO is a pair of satellites that chase each other around the Earth. The distance between them flexes by a hair as they fly over heavier or lighter ground, which is how they “feel” the mass of the ice below. The data is already turned into a map of mass change, so you get the headline number, gigatons of ice gained or lost, without doing any physics yourself. It’s the easiest starting point.
A “mascon” (short for mass concentration) is one tile of that map. Think of it as one pixel that reports how much mass it gained or lost since the mission’s baseline.
Then do four steps (the runnable code further down does all of this; this is just the idea):
- Pick your ice sheet. A latitude/longitude box around Greenland or Antarctica, plus the years you care about.
- Add up the mass. For each month, sum the mass change across all the mascon tiles inside your box. That gives you one number per month: how much ice was there compared to the starting point.
- Turn it into a trend. Fit a straight line through that monthly series. The slope is the mass-loss rate in gigatons per year (Gt/yr; a gigaton is a billion metric tons).
- Convert to sea level (optional). Every gigaton of meltwater that reaches the ocean raises global sea level by a fixed tiny amount (1 Gt water = 0.00277 mm), so multiply to get the contribution in mm/yr.
That’s the whole method. Below, “How a scientist answers this” names the exact tools, and the Run it cell does it live on synthetic data so you can see each step work.
What you can find out
- Total annual mass loss in Gt/yr (gigatons per year) from GRACE-FO, the headline number.
- Surface elevation change in m/yr from ICESat-2, a laser that measures the height of the ice surface instead of its mass. An independent second opinion.
- Spatial pattern of where loss is concentrated (West Antarctica, southeast Greenland, etc.).
- Sea-level-rise contribution in mm/yr equivalent (1 Gt of water = 0.00277 mm of global sea-level rise).
- Acceleration of the loss. It’s getting faster. Greenland’s canonical trend climbs from ~120 Gt/yr in 2002–2010 to ~280 Gt/yr in 2016–2022. If your numbers land near that, you built it right.
What it can’t tell you
- Melt water flowing under the glacier. The mass measurement is a single weight for the whole region; it can’t trace where the water goes beneath the ice. For that you’d need surface-meltwater products plus climate models.
- Anything before 2002. That’s when GRACE first flew, so the gravity record simply doesn’t exist earlier. Older estimates lean on different instruments (radar from orbit, earlier altimeters) and are shakier.
- The speed of a single outlet glacier. GRACE sees big regions, not individual glaciers. For per-glacier flow speed, use a separate product called ITS_LIVE (from NSIDC).
Gotchas to watch for
- GRACE-FO is blurry on purpose. Its resolution is roughly 1 degree (~100 km), so it’s honest about whole ice sheets but cannot pick out a single glacier. Don’t claim individual-glacier signals from GRACE alone.
- The ground itself is still rising. After the last Ice Age, the land under the ice is slowly springing back up now that the old weight is gone (this is called glacial isostatic adjustment, or GIA). That rebound looks like extra mass to GRACE, so it has to be subtracted. The fix is easy: use the GIA-corrected JPL mascon product (the one named above already accounts for this), never the raw version.
- Mass and height can disagree, and that’s useful. GRACE (mass) and ICESat-2 (surface height) sometimes diverge over fast outlet glaciers. That’s not an error. GRACE feels meltwater leaving below the surface, while ICESat-2 only sees the top. The gap between them is information.
- Turning height into mass needs a guess. If you go the ICESat-2 route, converting a height drop into a weight loss depends on how dense the snow/ice is (the “firn” density), which carries about 10–15% uncertainty. The mass-from-gravity route (GRACE) sidesteps this.
- There’s a gap in the record. The original GRACE mission ended and GRACE-FO began in 2017–2018, leaving a roughly one-year hole. Any trend that spans that gap is slightly less certain across it.
The real-data code
The Run it cell above runs the method on synthetic data (no login). Below is the whole recipe against the real archive: search the GRACE-FO mascons, open the grid, sum mass per month, fit the loss rate, convert to sea level, and plot it. It needs a free Earthdata Login.
import earthaccess, numpy as np, xarray as xr
from scipy import stats
import matplotlib.pyplot as plt
earthaccess.login(strategy="netrc")
aoi = (-75, 60, -10, 84) # your ice sheet as (W, S, E, N) — here, Greenland
start, end = "2002-04-01", "2024-12-31"
# 1. Find the GIA-corrected JPL mascon grid (one global file, monthly time steps).
grans = earthaccess.search_data(short_name="GRACEFO_L3_JPL_RL06.X_M",
bounding_box=aoi, temporal=(start, end))
ds = xr.open_mfdataset(earthaccess.open(grans), combine="by_coords")
# 2. Add up the mass inside the box, month by month. The mascons report liquid-water
# thickness (cm) per cell; multiply by each cell's area to get mass, then sum.
lwe = ds["lwe_thickness"].sel(lon=slice(aoi[0] % 360, aoi[2] % 360),
lat=slice(aoi[1], aoi[3])) # cm of water
lat = np.deg2rad(lwe.lat); dlon = dlat = np.deg2rad(0.5) # 0.5-deg grid
R = 6.371e6
cell_area = (R**2) * dlon * dlat * np.cos(lat) # m^2 per cell row
mass_cm_m2 = lwe * 0.01 * cell_area * 1000.0 # cm->m * area * rho -> kg
gt = (mass_cm_m2.sum(dim=("lat", "lon")) / 1e12).compute() # kg -> gigatons, per month
# 3. Fit a straight line through the monthly series -> mass-loss rate in Gt/yr.
t = (gt["time"] - gt["time"][0]) / np.timedelta64(365, "D") # years since start
t = t.values.astype(float); y = gt.values
ok = np.isfinite(y)
fit = stats.linregress(t[ok], y[ok])
rate = fit.slope # Gt/yr (negative = losing)
print(f"{('LOSING' if rate < 0 else 'gaining')} ice: {rate:+.0f} Gt/yr",
f"(r2={fit.rvalue**2:.2f}, p={fit.pvalue:.1e})")
# 4. Convert the loss rate to its sea-level contribution (1 Gt water = 0.00277 mm).
slr = -rate * 0.00277
print(f" -> sea-level contribution: {slr:+.2f} mm/yr")
# 5. Plot the cumulative mass curve with the fitted trend line.
plt.plot(t[ok], y[ok], ".", ms=4, label="GRACE-FO mass anomaly")
plt.plot(t[ok], fit.intercept + fit.slope * t[ok], "r-",
label=f"{rate:+.0f} Gt/yr")
plt.ylabel("mass anomaly (Gt)"); plt.xlabel("years since 2002")
plt.legend(); plt.tight_layout(); plt.show()
# Before you trust it: cross-check the gravity rate against ICESat-2 ATL06/ATL15 surface
# heights — they should agree on the sign; the gap between them over fast outlet glaciers
# is real signal, not error (see the gotchas).
Where the data comes from
Everything comes from NASA through one free login (Earthdata Login), but from two different archives. The gravity data (GRACE-FO) lives at PO.DAAC, NASA’s ocean and physical-oceanography archive. The laser-height data (ICESat-2) lives at the NSIDC DAAC, the snow-and-ice archive. The earthaccess library fetches from both with the same login, so you don’t have to think about where each one is stored.
Sources
- GRACE Tellus ice sheets: https://grace.jpl.nasa.gov/applications/ice-sheets/
- ICESat-2 ATL15: https://nsidc.org/data/atl15
- icepyx documentation: https://icepyx.readthedocs.io/
Make it yours → Edit the ice-sheet/basin bounding box, the date window, and the density assumption in the notebook to focus on Greenland, Antarctica, or a single drainage basin.
A safe place to practise the method on ATL06. The code is the real earthaccess workflow, but we feed it stand-in data shaped like the real product — so you can run it, change the numbers, and break it without an account. When you want the real data, use the recipe under “The real-data code” above, or download the notebook below.