q10·intermediate

Is Arctic sea ice breaking up earlier each year?

cryosphereoceanclimatesea-ice Datasets: 6 15–30 min

Sea ice is the frozen skin of seawater that covers the Arctic Ocean. It grows in winter and melts back in summer. How much of the ocean it covers on any given day is called the extent, basically the area that still has a lid of ice on it. Watch that area year after year and you can see whether the ice is melting away sooner each spring.

Is Arctic sea ice breaking up earlier each year?

Sea ice is the frozen skin of seawater that covers the Arctic Ocean. It grows in winter and melts back in summer. How much of the ocean it covers on any given day is called the extent, basically the area that still has a lid of ice on it. Watch that area year after year and you can see whether the ice is melting away sooner each spring.

Which data to use, and how

Use this dataset: NSIDC Sea Ice Index (short name G02135). It’s the official record of how much Arctic ocean is covered by ice each day, going back to 1979. The big bonus for a beginner: it ships as a plain CSV file you can download with no login at all. One date column, one ice-area column, ready to plot. (Later, for ice thickness instead of area, you’d reach for the satellite-laser dataset ICESat-2 ATL10. Skip that for your first pass.)

Then do four steps (the runnable code further down does all of this; this is just the idea):

  1. Grab the CSV: download the daily sea-ice-extent file and load it into a table with a date column and an extent column.
  2. Trim to recent years: keep, say, the last 30 years so you’re comparing a consistent stretch.
  3. Find the yearly low point: for each year, locate the date when the ice shrinks to its smallest (its annual minimum, usually around late September). You can also pick a “breakup date”, the day the ice in your region drops below half its winter coverage.
  4. Plot that date against the year: line up “minimum/breakup date” on one axis and “year” on the other. A line sloping toward earlier dates means the ice is breaking up sooner each year. Flat means no real change.

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

  • Whether the ice is shrinking: the area covered by sea ice, year by year since 1979.
  • When the yearly low happens: the date of the minimum extent (typically late September), and whether that date is trending.
  • Region-by-region breakup timing: when individual seas open up (Beaufort, Chukchi, Kara, Laptev).
  • How thick the ice is: using the ICESat-2 laser (2018 onward), which measures the ice’s height above the water and converts that to thickness.
  • The loss of old ice: the shrinking fraction of tough multi-year ice (ice that has survived more than one summer), a classic fingerprint of a warming climate.

What it can’t tell you

  • What individual ice floes are doing day to day. Tracking the cracking and drifting of single ice slabs needs radar imagery (Sentinel-1) fused with the ICESat-2 laser. The extent record is too coarse for that.
  • What’s happening in the water below the ice. The ice records say nothing about ocean temperature or currents under the lid. For that you’d combine with an ocean model (PO.DAAC ECCO).
  • Anything before 1979. That year is the start of the continuous satellite record. Earlier than that, there simply isn’t consistent daily coverage to compare against.

Gotchas to watch for

  • Use the Sea Ice Index for any “extent” claim. Several datasets report ice area, but the NSIDC Sea Ice Index is the reference everyone cites. Start and end with it so your numbers match published work.
  • Thickness is fuzzier than area. Turning the laser’s height-above-water measurement (called freeboard) into actual thickness needs an assumption about how much snow sits on top, and that adds roughly 30 cm of uncertainty depending on which snow-depth product you use. The area record has no such guesswork, another reason to start there.
  • Reproduce the famous decline as a sanity check. The September-minimum extent has been dropping about 12.7% per decade, the single most-cited number in Arctic climate. If your code recovers something close to that, you’ve probably built it right; if not, suspect the code, not the planet.
  • The Antarctic is a different story. Don’t assume the South Pole mirrors the North. Antarctic sea ice showed no clear one-way trend until a sudden 2016 drop, a separate scientific puzzle, so don’t copy Arctic conclusions onto 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: grab the Sea Ice Index CSV, trim to recent years, find each year’s minimum-extent date, fit a robust trend on that date (and on the September minimum), print the verdict, and plot it. The CSV needs no login; the optional ATL10 thickness step needs a free Earthdata Login.

import earthaccess, numpy as np, pandas as pd
import pymannkendall as mk
import matplotlib.pyplot as plt

# 1. Grab the NSIDC Sea Ice Index daily extent CSV (the reference record, no login).
url = ("https://noaadata.apps.nsidc.org/NOAA/G02135/north/daily/"
       "data/N_seaice_extent_daily_v3.0.csv")
raw = pd.read_csv(url, skiprows=[1])                      # row 1 is a units line
raw.columns = [c.strip().lower() for c in raw.columns]
raw["date"] = pd.to_datetime(dict(year=raw.year, month=raw.month, day=raw.day))
ext = raw[["date", "extent"]].dropna().sort_values("date")  # extent in 10^6 km^2

# 2. Trim to the last 30 complete years so we compare a consistent stretch.
last = ext["date"].dt.year.max() - 1
ext = ext[(ext["date"].dt.year >= last - 29) & (ext["date"].dt.year <= last)].copy()
ext["year"] = ext["date"].dt.year
ext["doy"]  = ext["date"].dt.dayofyear

# 3. For each year, find the annual minimum: its date (day-of-year) and its extent.
#    The melt-season low sits in late summer, so ignore the Jan/Feb winter floor.
melt = ext[ext["doy"] >= 150]                            # June onward
idx  = melt.groupby("year")["extent"].idxmin()
ann  = melt.loc[idx, ["year", "doy", "extent"]].set_index("year").sort_index()

# 4. Robust trends: Theil-Sen slope + Mann-Kendall significance on both the
#    minimum DATE and the September-minimum EXTENT (the famous ~12.7%/decade decline).
date_trend = mk.original_test(ann["doy"].values)
ext_trend  = mk.original_test(ann["extent"].values)
mean_ext   = ann["extent"].mean()
decline_pc = ext_trend.slope * 10 / mean_ext * 100       # % of mean per decade

earlier = "earlier" if date_trend.slope < 0 else "later"
print(f"Annual minimum is arriving {earlier}: "
      f"{date_trend.slope:+.2f} days/yr, p={date_trend.p:.3f} "
      + ("(significant)" if date_trend.h else "(not distinguishable from noise)"))
print(f"September-minimum extent trend: {decline_pc:+.1f}% per decade "
      f"(published ~ -12.7%/decade)")

# 5. Plot the minimum extent and its date against the year.
fig, ax = plt.subplots(2, 1, sharex=True, figsize=(7, 6))
ax[0].plot(ann.index, ann["extent"], "o-"); ax[0].set_ylabel("min extent (10^6 km^2)")
ax[1].plot(ann.index, ann["doy"], "o-");    ax[1].set_ylabel("min date (day of year)")
ax[1].set_xlabel("year"); fig.suptitle("Arctic sea ice annual minimum")
fig.tight_layout(); plt.show()

# Optional: for ice THICKNESS (not area), search the ICESat-2 laser archive and
# read freeboard along the strong beams with h5py, converting to thickness with an
# assumed snow depth (NESOSIM / W99) — that snow guess adds ~30 cm of uncertainty.
earthaccess.login(strategy="netrc")
atl10 = earthaccess.search_data(short_name="ATL10", bounding_box=(-180, 65, 180, 88),
                                temporal=("2018-10-01", "2025-12-31"))
print(f"{len(atl10)} ATL10 freeboard granules available for thickness follow-up")

# Sanity check: the September-minimum extent decline above should land near the
# published -12.7%/decade — if it does, trust the date trend; if not, suspect the code.

Where the data comes from

Almost everything here comes from a single NASA archive, the NSIDC (the National Snow and Ice Data Center), which holds the ICESat-2 laser data, the AMSR-2 microwave data, and the Sea Ice Index. The Sea Ice Index CSV is free and needs no login at all. The satellite searches need one free Earthdata Login.

Sources

How a scientist answers this
Parameters
Daily sea-ice extent (million km2) from the NSIDC Sea Ice Index (G02135, passive-microwave continuity since 1979) and AMSR-2 ice concentration; sea-ice thickness from ICESat-2 ATL10 freeboard (2018+, converted via a snow-depth assumption); MODIS/VIIRS for cloud-free imagery context. Breakup/minimum dates are derived per region (Beaufort, Chukchi, Kara, Laptev) against a regional concentration threshold (commonly 15%).
Method
Define breakup as the day concentration/extent in a region falls below the threshold, extract that date each year, and fit a Theil–Sen + Mann–Kendall trend (days/decade) on the breakup-date and minimum-extent series; complement with the multi-year-ice-fraction decline. Robust trend statistics handle the year-to-year variability.
Validation
Use the long passive-microwave record but flag the sensor/algorithm changes spliced into it and the melt-season concentration biases from surface melt ponds; cross-check thickness assumptions (snow depth dominates ATL10 freeboard-to-thickness error) and confirm regional trends against the NSIDC Sea Ice Index.
In plain EnglishFor each region, find the day every year when the ice cover drops below a set level, then see whether that breakup day is creeping earlier over the decades. Robust statistics separate a real trend from the natural noisy ups and downs.

Make it yours → Set the region/sector, the concentration threshold, and the year range in the notebook to compute breakup-date trends for your area.

🧪 Virtual Mock Lab stand-in data · runs in your browser · no login

A safe place to practise the method on ATL10. 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.

editable · runs in your browser
Recipe ready · not yet run The recipe and the Virtual Mock Lab above are ready to use. We haven't yet run this question end-to-end on real data, so it has no verified answer yet — only the questions we've actually computed carry one. That's the honest line between a method and a result.