Where are the productive, fish-rich waters off my coast — and when do they bloom?
Draw a rectangle, then check which collections cover it. Most NASA data is global, so a big box matches a lot.
-123.5, 36.5 → -121.5, 38.5 (California upwelling coast, USA)Fish gather where the food is, and the ocean's food chain starts with phytoplankton, the microscopic floating plants. They contain chlorophyll, the same green pigment as land plants, and satellites can see it as a faint colour change in the seawater. More chlorophyll means more phytoplankton, which usually means a more productive sea with more fish feeding higher up the chain. NASA satellites have mapped this colour globally since 2002, so you can watch where and when your coast's productive waters light up.
Where are the productive, fish-rich waters off my coast — and when do they bloom?
Fish gather where the food is, and the ocean’s food chain starts with phytoplankton, the microscopic floating plants. They contain chlorophyll, the same green pigment as land plants, and satellites can see it as a faint colour change in the seawater. More chlorophyll means more phytoplankton, which usually means a more productive sea with more fish feeding higher up the chain. NASA satellites have mapped this colour globally since 2002, so you can watch where and when your coast’s productive waters light up.
Which data to use, and how
Use this dataset: MODIS-Aqua chlorophyll (short name
MODISA_L3m_CHL). It’s a ready-to-use global map of chlorophyll concentration going back to
2002, so it’s the easiest place to start and gives you the longest history. Want sharper, more
recent detail? PACE chlorophyll (PACE_OCI_L3M_CHL) is NASA’s
newer ocean-colour mission. Same idea, finer colour detail, but only for recent dates. Begin with
MODIS, add PACE only if you need today’s sharper picture.
Then do four steps (the runnable code further down does all of this; this is just the idea):
- Pick your coast. A small latitude/longitude box over the water you care about, plus a date or month.
- Read the chlorophyll. Open the map and slice out your box. The value is in mg/m³ (milligrams of chlorophyll per cubic metre of seawater). Bright high values mean productive water, near-zero means open-ocean “desert”.
- Find the bloom season. Repeat for each month across the years and take the typical value per month (a “climatology”). The months that spike are your bloom season.
- Check why it’s there. Overlay sea-surface temperature
(
MUR-JPL-L4-GLOB-v4.1). Cold patches are where deep, nutrient-rich water rises to the surface (upwelling), and those cold tongues line up with the chlorophyll blooms.
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.
Verified locally. For the California upwelling coast (36.5–38.5 °N), the MODIS chlor_a field
read a median of 2.81 mg/m³ in July 2024. That’s high, typical of a cool, nutrient-rich
upwelling system, and far above the open ocean’s ~0.1 mg/m³.
What you can find out
- Where the productive water is. Map the chlorophyll; bright bands hug coasts, upwelling zones, and river mouths.
- When it blooms. Build a month-by-month average to see the seasonal peak (spring/summer in most upwelling systems).
- Whether this year is early, late, weak or strong. Compare this season’s chlorophyll to the multi-year normal.
- Why it’s there. Overlay sea-surface temperature; cold upwelling fronts line up with the blooms, warm stagnant water with the empty “deserts”.
- How conditions shifted after an event. Track chlorophyll before and after a storm, a marine heatwave, or an El Niño phase.
What it can’t tell you
- How many fish are there. Chlorophyll measures the base of the food web (the plant food), not the fish themselves. Counting actual fish needs catch records and survey data, a separate kind of science (a “stock assessment”).
- What’s happening below the surface. Ocean colour only senses the sunlit top layer of water, so a chlorophyll-rich layer sitting deeper down is invisible.
- Anything under cloud. These are optical sensors. They see no colour through cloud. The ready-made maps fill the gaps by averaging over time, which can blur a short, sharp bloom.
- The true value right next to land. Very muddy or shallow water (bays, river plumes) fools the standard chlorophyll calculation, so coastal pixels can be off. Use them with care.
- Which kind of plankton it is. High chlorophyll doesn’t say whether the bloom is harmless or toxic; for harmful algae, see the harmful-algal-bloom questions.
Gotchas to watch for
- Latitudes run north→south. In these maps the rows go from north at the top down to south, so
when you slice your box you ask for
slice(North, South), north first. Get it backwards and you get an empty result. It’s the single most common silent bug here. - Clouds leave gaps. Optical sensors can’t see ocean colour through cloud, so a single day can be mostly blank over your coast. The fix: use the time-averaged maps (or average a whole month yourself) so clear days fill the holes, at the cost of smearing out brief blooms.
- Coast pixels lie. Near land, mud and shallow bottoms make the chlorophyll algorithm read too high. The fix: trust the open-coast water more than pixels jammed against the shoreline, bays, or plumes.
- Always compare like with like. Chlorophyll has a strong season, so compare the same month across years (July vs July), never July vs January, when judging if a year is unusual.
The real-data code
The Run it cell above runs this method on synthetic data with no login. Below is the whole recipe against the real archive: search, open, slice the box, build the monthly climatology to find the bloom season, then overlay MUR sea-surface temperature to see the cold upwelling fronts. It needs a free Earthdata Login.
import earthaccess, numpy as np, xarray as xr
import matplotlib.pyplot as plt
earthaccess.login(strategy="netrc")
W, S, E, N = -123.5, 36.5, -121.5, 38.5 # your coast as (W,S,E,N) — California upwelling
years = range(2014, 2024)
# 1. One chlorophyll number per month: open each monthly MODIS-Aqua map, slice the box
# (lat runs N->S in these maps, so slice North first), take the median (robust to coast
# pixels and cloud-gap outliers). chlor_a is mg/m^3.
def box_chl(short_name, y, m):
g = earthaccess.search_data(
short_name=short_name, temporal=(f"{y}-{m:02d}-01", f"{y}-{m:02d}-28"))
if not g:
return np.nan
ds = xr.open_dataset(earthaccess.open(g[:1])[0], engine="h5netcdf")
chl = ds["chlor_a"].sel(lat=slice(N, S), lon=slice(W, E))
return float(np.nanmedian(chl))
series = np.array([[box_chl("MODISA_L3m_CHL", y, m) for m in range(1, 13)] for y in years])
# 2. Bloom season: the typical (climatological) value for each calendar month across the years.
clim = np.nanmedian(series, axis=0)
peak = int(np.nanargmax(clim)) + 1
print(f"Bloom peaks in month {peak}: {clim[peak-1]:.2f} mg/m^3 "
f"vs {np.nanmin(clim):.2f} mg/m^3 at the lean season "
f"(open-ocean 'desert' is ~0.1 mg/m^3).")
# 3. Why it's there: pull MUR sea-surface temperature for the peak month and check the box
# mean is cool — cold water is deep, nutrient-rich water upwelling to feed the bloom.
gt = earthaccess.search_data(
short_name="MUR-JPL-L4-GLOB-v4.1",
temporal=(f"{years[-1]}-{peak:02d}-15", f"{years[-1]}-{peak:02d}-15"))
sst = xr.open_dataset(earthaccess.open(gt[:1])[0], engine="h5netcdf")["analysed_sst"]
sst = sst.sel(lat=slice(S, N), lon=slice(W, E)) - 273.15 # MUR lat runs S->N; K -> degC
print(f"Box-mean SST in the bloom month: {float(sst.mean()):.1f} degC (cool = upwelling).")
# 4. Plot the bloom calendar.
plt.bar(range(1, 13), clim)
plt.axvline(peak, ls="--", c="k", label=f"bloom peak (month {peak})")
plt.ylabel("chlorophyll (mg/m^3)"); plt.xlabel("month"); plt.legend()
plt.tight_layout(); plt.show()
# Before you trust it: cross-check against PACE chlorophyll (short_name="PACE_OCI_L3M_CHL")
# for recent dates, and remember coast pixels read too high (mud/shallows) — see the gotchas.
Where the data comes from
All from NASA through one free login (Earthdata Login). The chlorophyll maps (MODIS and PACE) come from NASA’s ocean-colour archive (OB.DAAC); the sea-surface temperature comes from the physical-oceanography archive (PO.DAAC). To frame your fishing zone or coastline neatly, you can add free boundary files (geoBoundaries, or a country’s Exclusive Economic Zone). Those are separate and not from NASA.
Sources
- MODIS-Aqua chlorophyll (
MODISA_L3m_CHL): https://oceancolor.gsfc.nasa.gov/ - NASA PACE mission: https://pace.gsfc.nasa.gov/
- MUR sea-surface temperature (
MUR-JPL-L4-GLOB-v4.1): https://podaac.jpl.nasa.gov/dataset/MUR-JPL-L4-GLOB-v4.1
Make it yours → Choose the coastal box, months, and chlorophyll source (MODIS vs PACE), and adjust the bloom-threshold and climatology years in the notebook.
A safe place to practise the method on MODISA_L3m_CHL. 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.