qin6·intermediate

Is my region shifting from one crop a year to two or three?

biosphereagriculturelandfood-security Datasets: 4 15–30 min
Find the data for your area

Draw a rectangle to pick your area of interest, then see what NASA data covers it (live, here in your browser) or download a ready-to-run notebook with your AOI pre-filled. The notebook runs in any Python environment — it needs a free Earthdata Login to fetch the data.

Current AOI: 74, 29.5 → 77, 32 (Punjab)
On this page

Is my region shifting from one crop a year to two or three?

What you can answer

  • Cropping intensity per year — single / double / triple cropping from counted NDVI cycles
  • Change in intensity over time — where cycles-per-year are rising across the record
  • Spatial map of intensification — which sub-regions added a season
  • Crop-calendar timing — when each green-up and senescence occurs through the year
  • Coarse vs fine comparison — MODIS 250 m trend vs HLS 30 m for fragmented fields

What you can NOT answer with these alone

  • Which crop is grown — NDVI cycles count seasons, not species; pair with crop-type maps or ground truth.
  • Exact field boundaries at MODIS scale — 250 m pixels mix multiple smallholder plots; use HLS/Sentinel-2 30 m.
  • Irrigated vs rain-fed cause without ancillary data — a second cycle implies irrigation/residual moisture but doesn’t prove the water source.
  • Yield or production — cycle count is intensity, not output; combine with yield models and census data.

Code template

import earthaccess
import xarray as xr
import numpy as np
from scipy.signal import savgol_filter, find_peaks

earthaccess.login(strategy="netrc")

# AOI: Punjab
aoi = (74, 29.5, 77, 32)
years = range(2010, 2026)

# Greenness / amplitude rules — tune and verify against local crop calendars
ndvi_threshold = 0.4    # peak must exceed this to count as a crop cycle
min_prominence = 0.15   # min NDVI rise/fall so noise isn't counted as a crop

def cycles_per_year(ndvi_1d):
    """Count crop cycles in one year's NDVI series (already time-ordered)."""
    smooth = savgol_filter(ndvi_1d, window_length=5, polyorder=2)
    peaks, _ = find_peaks(smooth, height=ndvi_threshold,
                          prominence=min_prominence)
    return len(peaks)

# 1. MODIS NDVI (16-day, 250 m) across the year range
granules = earthaccess.search_data(short_name="MOD13Q1",
                                   bounding_box=aoi,
                                   temporal=(f"{min(years)}-01-01",
                                             f"{max(years)}-12-31"))
# Open NDVI (scale ×0.0001), apply the VI QA/pixel-reliability mask,
# stack to a (time, y, x) DataArray, then per pixel per crop-year:
#   intensity[year] = cycles_per_year(ndvi_series_for_that_year)

# 2. Trend: regress intensity vs year per pixel → map of rising cropping
#    (positive slope = shifting toward double/triple cropping).

# 3. (Optional) HLS 30 m for smallholder fields where 250 m mixes plots
#    short_name="HLSS30" / "HLSL30"; same cycle-counting on a finer grid.

# 4. Mask to cropland (e.g. a land-cover product) so forest/grass green-up
#    is not miscounted as a crop cycle.

Expected output

  • Per-year cropping-intensity map (1 / 2 / 3 crops) from counted NDVI cycles
  • Intensity-trend map — slope of cycles-per-year over the record (intensifying vs stable)
  • NDVI-vs-time curves for sample pixels showing one, two, or three green waves
  • Summary: share of the AOI that gained a cropping season over the period

Caveats

  • Mixed pixels at 250 m — a MODIS pixel can blend several fields with different calendars, smearing or double-counting cycles; use HLS 30 m for smallholder landscapes.
  • Natural vegetation greens up too — forest, grassland, and weeds produce NDVI cycles; mask to cropland before counting.
  • Cloud/monsoon gaps — kharif-season cloud cover thins the NDVI record; smooth and gap-fill, and use pixel-reliability QA.
  • Threshold/amplitude rules are tunable, not universal — the greenness cutoff and prominence depend on crop and region; calibrate locally rather than asserting one value.
  • Verify the shift against the census — cross-check any intensification trend with agricultural-census / district crop statistics before claiming a real change.

Cross-DAAC composition

LP DAAC only for the core workflow (MODIS MOD13, HLS) — single DAAC, single Earthdata auth. Optional cropland masks (e.g. national land-cover products) may add a second source.

Sources

How a scientist answers this
Parameters
Vegetation-index time series (MODIS MOD13 NDVI/EVI, 16-day, 250 m, 2000–present; or HLS/Sentinel-2 at 30 m for smaller fields). Each NDVI green-up → peak → senescence cycle within a year corresponds roughly to one crop, so the number of cycles per year is the cropping intensity (single / double / triple), and its change over years is the trend you want.
Method
Build the per-pixel NDVI/EVI time series, smooth out noise and cloud gaps (e.g. Savitzky–Golay or a temporal composite), then count the green-up/senescence cycles per crop-year that exceed a greenness threshold and a minimum amplitude — one peak ≈ one crop. Track the cycle count year over year and map where intensity is rising (1→2→3 crops). Use a relative amplitude/persistence rule rather than one fixed NDVI value so it travels across regions and sensors.
Validation
At MODIS 250 m a pixel often mixes several smallholder fields, blurring or double-counting cycles — drop to HLS/Sentinel-2 30 m for fragmented landscapes. Separate crops from natural vegetation (forest/grassland also green up) using cropland masks, distinguish irrigated double-cropping from rain-fed single seasons, and cross-check the intensity trend against the agricultural census / district crop statistics before claiming a shift.
In plain EnglishEach time a field turns green and then browns off, that's roughly one crop. Counting those green waves per year tells you whether a place grows one, two, or three crops — and watching that count climb over the years shows intensification.

Make it yours → Pick your region and year range, set the greenness threshold and smoothing, and the notebook counts crop cycles per year and maps the change. Switch from MODIS 250 m to HLS 30 m when fields are small.

Run the core method · no login

The robust trend (Theil–Sen + Mann–Kendall) at the heart of this question — runnable on synthetic data, right here. The full earthaccess code template further down does it on real NASA data (needs an Earthdata login).

editable · runs in your browser

Datasets used