FIRMS quickstart — recent active fires¶
Fetch recent active-fire detections (MODIS / VIIRS) from NASA FIRMS through the earthlens FIRMS backend, and plot the fire pixels coloured by fire radiative power (FRP).
FIRMS is a vector backend: download() returns a pyramids FeatureCollection (a geopandas.GeoDataFrame, CRS EPSG:4326), one row per fire pixel.
Setup¶
Pull in the imports up front: EarthLens is the unified entry point and matplotlib.pyplot is used for the final scatter. We also prepare an output directory — FIRMS is a file-writing-plus-in-memory vector backend, so download() writes the detections to firms_output/ and returns them as a GeoDataFrame.
import datetime as dt
import os
from pathlib import Path
import matplotlib.pyplot as plt
from earthlens import EarthLens
OUT_DIR = Path('firms_output')
OUT_DIR.mkdir(exist_ok=True)
Credentials¶
FIRMS needs a free MAP_KEY (https://firms.modaps.eosdis.nasa.gov/api/map_key/). Set FIRMS_MAP_KEY in your environment; the live cells below skip cleanly when it is absent, so the notebook never fails offline.
HAS_KEY = bool(os.environ.get('FIRMS_MAP_KEY'))
print('FIRMS_MAP_KEY set:', HAS_KEY)
Query¶
variables is a list of FIRMS sensor codes (not data variables). We use the 375 m VIIRS S-NPP near-real-time sensor over Southern California for a recent 7-day window. FIRMS caps requests at 10 days / one sensor, but the backend chunks longer windows transparently.
Date window¶
FIRMS near-real-time retains only the most recent ~2 months, so we anchor the window to a recent 7-day span ending today.
TODAY = dt.date.today()
START = (TODAY - dt.timedelta(days=7)).strftime('%Y-%m-%d')
END = TODAY.strftime('%Y-%m-%d')
Build the request and download¶
We build the EarthLens request first — source, sensor (variables), date window, bounding box, and output path — then call download() as a separate step. The whole thing stays inside a guard so the notebook skips cleanly when no MAP_KEY is set or the live query fails. The result is written to firms_output/ and returned in memory.
fires = None
if HAS_KEY:
try:
request = EarthLens(
data_source='firms',
variables=['VIIRS_SNPP_NRT'],
start=START,
end=END,
aoi=[-119.0, 33.0, -117.0, 35.0],
path=str(OUT_DIR),
)
fires = request.download(progress_bar=False)
print('detections:', len(fires))
except Exception as exc: # keep the notebook safe offline
print('skipped live query:', exc)
Inspect the detections¶
Every row is one fire pixel with a normalised confidence_pct and frp (MW).
if fires is not None and len(fires):
cols = [
'acq_datetime',
'sensor',
'confidence',
'confidence_pct',
'brightness_k',
'frp',
'daynight',
'geometry',
]
display(fires[cols].head())
print('CRS:', fires.crs)
Plot the fire pixels coloured by FRP¶
Plotting the GeoDataFrame directly with column='frp' colours each detection by its fire radiative power, so the most intense pixels stand out.
if fires is not None and len(fires):
ax = fires.plot(column='frp', cmap='inferno', markersize=18, alpha=0.7, legend=True)
ax.set_title(f'FIRMS VIIRS detections, {START} to {END} (colour = FRP, MW)')
ax.set_xlabel('longitude')
ax.set_ylabel('latitude')
plt.show()