Are the coral reefs near me heading for a bleaching summer?
Draw a rectangle, then check which collections cover it. Most NASA data is global, so a big box matches a lot.
-81.8, 24.4 → -80.2, 25.2 (Florida Keys reef tract, USA)Corals are living animals. They bleach (turn ghostly white and start to die) when the seawater around them stays too warm for too long. One hot afternoon doesn't do it. Weeks of heat piling up does. So the early-warning signal for a bad bleaching summer is simple: how hot the sea surface has been, day after day. A satellite can measure that for any reef on Earth, even one with no buoy nearby.
Are the coral reefs near me heading for a bleaching summer?
Corals are living animals. They bleach (turn ghostly white and start to die) when the seawater around them stays too warm for too long. One hot afternoon doesn’t do it. Weeks of heat piling up does. So the early-warning signal for a bad bleaching summer is simple: how hot the sea surface has been, day after day. A satellite can measure that for any reef on Earth, even one with no buoy nearby.
Which data to use, and how
Use this dataset: MUR sea surface temperature (short
name MUR-JPL-L4-GLOB-v4.1). “Sea surface temperature” (SST) is the temperature of the top
skin of the ocean. MUR gives you a daily, gap-free map at ~1 km, going back to 2002, so you
can watch a reef’s water heat up through a summer and line it up against past years. One catch:
MUR stores temperature in kelvin (a scientist’s scale), so to get familiar °C you subtract 273.15.
Then do four steps (the runnable code further down does all of this; this is just the idea):
- Pick your reef (a small latitude/longitude box around it) and the summer you care about.
- One number per day. Average the SST inside your box for each day, giving a daily temperature series. Convert kelvin to °C as you go.
- Build a “normal” from past years. For each calendar day, average that day across many years (a climatology, the typical seasonal pattern). This year minus the normal is the anomaly, the warm departure that drives bleaching.
- Count the dangerous days. Add up how many days the reef sat above its heat threshold (the standard trigger is the local “maximum monthly mean + 1 °C”). More days over the line means more bleaching pressure.
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
- How warm the water over a reef is right now, and every day back to 2002, from MUR
analysed_sst(remember: stored in kelvin, subtract 273.15 for °C). - Whether this summer is hotter than normal. Build the per-day climatology from past years and plot this year’s anomaly.
- How many days the reef sat above its bleaching threshold. Count days over the local “maximum monthly mean + 1 °C”, the standard bleaching trigger.
- The official heat-stress level. Overlay NOAA Coral Reef Watch Degree Heating Weeks (DHW), the validated score that turns weeks of accumulated heat into a bleaching alert level. It’s free and needs no login.
- Water-clarity context. Pull in MODIS chlorophyll-a (chlorophyll-a is a stand-in for how green or murky the water is from algae), since murky or nutrient-loaded water interacts with heat stress.
Verified locally: for the Florida Keys reef tract (24.4–25.2 °N), the MUR analysed_sst field
read 30.9 °C on 10 Aug 2024 — already in the range where prolonged exposure stresses corals.
What it can’t tell you
- Whether corals actually bleached. SST is the driver of bleaching, not proof of it. Heat stress raises the risk. Confirming an actual bleaching event needs people in the water doing surveys, or high-resolution imagery.
- The exact temperature down on the reef floor. MUR is a blended surface map at 1 km. A shallow back-reef lagoon can run hotter than the 1 km average suggests.
- Which species are in trouble. Bleaching thresholds vary by coral species and by how much heat a particular reef has already lived through. A single number can’t capture that.
- Fine, sub-kilometre detail. For one specific patch of reef, 1 km pixels are coarse. You’d pair MUR with finer per-overpass (L2) SST or in-water temperature loggers.
Gotchas to watch for
- Temperature comes in kelvin. MUR’s
analysed_sstis in kelvin (a scale starting at absolute zero), so raw values look like ~300, not ~27. Forget to subtract 273.15 and every threshold check turns into nonsense, so convert to °C the moment you read the data. - Heat is cumulative, not a single hot day. One scorching day rarely bleaches a reef; it’s weeks above the threshold that do. A “today’s temperature” check badly undersells the danger. Count days over the threshold across the whole summer instead, and for the real answer lean on NOAA’s Degree Heating Weeks, which sums up the accumulated heat for you.
- A 1 km pixel is an average, not your exact reef. The value over a small reef is blended across ~1 km of ocean, so a hot shallow lagoon can run warmer than MUR shows and you can end up underestimating local stress. Treat MUR as the regional signal and, if you need the exact spot, add in-water loggers.
- Don’t reinvent the official metric. A homegrown “30 °C” threshold is a fine teaching version, but it isn’t the official number. The validated bleaching score (Degree Heating Weeks and alert levels) already exists, free, from NOAA Coral Reef Watch, so use your own count to learn and then cross-check against Coral Reef Watch for the real call.
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 MUR, open each daily NetCDF and slice your reef’s box, build a
per-day climatology from past years, take this summer’s anomaly, count the days over the bleaching
threshold, and plot it. MUR-JPL-L4-GLOB-v4.1, variable analysed_sst, is a global daily NetCDF —
slice the bounding box before reading so you never download the whole globe, and values are in
kelvin. It needs a free Earthdata Login.
import os, re, earthaccess, xarray as xr, numpy as np
import matplotlib.pyplot as plt
# load Earthdata creds from .env without `source` (passwords can break the shell)
for line in open(".env"):
m = re.match(r'\s*(?:export\s+)?([A-Z0-9_]+)\s*=\s*(.*)\s*$', line)
if m: os.environ.setdefault(m.group(1), m.group(2).strip().strip('"').strip("'"))
earthaccess.login(strategy="environment") # free Earthdata Login
W, S, E, N = -81.8, 24.4, -80.2, 25.2 # your reef (Florida Keys), as (W,S,E,N)
SUMMER, BASELINE = 2024, range(2003, 2024) # this summer vs the multi-year normal
# 1. One SST number per day inside the reef box, kelvin -> °C, for any [start,end].
def daily_sst(start, end):
grans = earthaccess.search_data(short_name="MUR-JPL-L4-GLOB-v4.1",
temporal=(start, end))
out = {}
for fh in earthaccess.open(grans):
ds = xr.open_dataset(fh, engine="h5netcdf")
box = ds["analysed_sst"].sel(lat=slice(S, N), lon=slice(W, E)) - 273.15
doy = int(ds["time"].dt.dayofyear) # day-of-year keys the climatology
out[doy] = float(box.mean())
return out
# 2. This summer's daily series (Jun–Sep), one mean SST per day.
this_year = daily_sst(f"{SUMMER}-06-01", f"{SUMMER}-09-30")
doys = sorted(this_year)
obs = np.array([this_year[d] for d in doys])
# 3. Build the "normal": for each summer day, average that calendar day across past years.
clim = {d: [] for d in doys}
for y in BASELINE:
past = daily_sst(f"{y}-06-01", f"{y}-09-30")
for d in doys:
if d in past: clim[d].append(past[d])
normal = np.array([np.mean(clim[d]) for d in doys])
anomaly = obs - normal # warm departure that drives bleaching
# 4. Count the dangerous days: the standard trigger is "max monthly mean + 1 °C".
# Approximate MMM from the baseline climatology, then count days over MMM+1.
mmm = float(np.max(normal)) # warmest typical summer day = ~MMM
threshold = mmm + 1.0
hot_days = int(np.sum(obs > threshold))
verdict = "HEADING FOR TROUBLE" if hot_days >= 14 else "elevated but below alarm"
print(f"{verdict}: {hot_days} days over {threshold:.1f} °C in summer {SUMMER}; "
f"peak SST {obs.max():.1f} °C, peak anomaly {anomaly.max():+.1f} °C")
# 5. Plot this summer vs the normal, with the bleaching threshold marked.
plt.plot(doys, normal, c="gray", label="normal (baseline mean)")
plt.plot(doys, obs, c="crimson", label=f"summer {SUMMER}")
plt.axhline(threshold, ls="--", c="k", label=f"threshold {threshold:.1f} °C")
plt.xlabel("day of year"); plt.ylabel("reef SST (°C)")
plt.legend(); plt.tight_layout(); plt.show()
# Before you trust it: cross-check against NOAA Coral Reef Watch Degree Heating Weeks
# (the validated, free metric) — and remember a 1 km pixel averages over your exact reef.
Where the data comes from
The sea-surface temperature (MUR) comes from NASA through one free login (Earthdata Login); it’s served from the PO.DAAC ocean archive as daily NetCDF files. The official heat-stress score (Degree Heating Weeks and bleaching alerts) comes from NOAA Coral Reef Watch, a separate US agency, and is free with no login at all. Optional extras: MODIS chlorophyll-a (water clarity context, from NASA’s ocean-colour archive) and free geoBoundaries outlines to put a name on the coastline you’re looking at.
Sources
- MUR SST (PO.DAAC): https://podaac.jpl.nasa.gov/dataset/MUR-JPL-L4-GLOB-v4.1
- NOAA Coral Reef Watch (Degree Heating Weeks & bleaching alerts): https://coralreefwatch.noaa.gov/
- MODIS-Aqua chlorophyll-a (OB.DAAC): https://oceancolor.gsfc.nasa.gov/
- geoBoundaries (admin boundaries): https://www.geoboundaries.org/
Make it yours → Set the reef bounding box, the season/years, and the MMM+threshold in the notebook, and toggle between self-computed DHW and the NOAA Coral Reef Watch product.
A safe place to practise the method on MUR-JPL-L4-GLOB-v4.1. 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.