Quick Start Guide#
Let’s create your first multi-seasonal NDVI analysis with Ndvi2Gif!
Your First NDVI Analysis#
This example creates a seasonal NDVI composite for a region using Sentinel-2 data.
Step 1: Import and Initialize#
import ee
import geemap
from ndvi2gif import NdviSeasonality
# Initialize Earth Engine
ee.Initialize(project='your-project-id')
Step 2: Define Your Region of Interest (ROI)#
There are multiple ways to define your ROI:
Option A: Draw on a Map#
# Create an interactive map
Map = geemap.Map()
Map.centerObject(ee.Geometry.Point([-3.7, 40.4]), 10) # Madrid, Spain
Map
# Draw a polygon on the map, then:
roi = Map.user_roi
Option B: Use Coordinates#
# Define a bounding box
roi = ee.Geometry.Rectangle([-3.8, 40.3, -3.6, 40.5])
# Or a point with buffer
roi = ee.Geometry.Point([-3.7, 40.4]).buffer(5000) # 5km radius
Option C: Use a Shapefile#
# Load from a shapefile
roi = 'path/to/your/area.shp'
Step 3: Create an NDVI Composite#
# Initialize the processor
ndvi_processor = NdviSeasonality(
roi=roi,
sat='S2', # Sentinel-2
periods=12, # Monthly composites
start_year=2023,
end_year=2024,
index='ndvi', # Normalized Difference Vegetation Index
key='median' # Use median for cloud-free composites
)
Step 4: Get the Composite#
# get_year_composite() returns an ee.ImageCollection with one image per year.
# Each image has one band per period (january, february, ..., december).
all_composites = ndvi_processor.get_year_composite()
# Select a single year's composite (here, the first year in the range)
composite = all_composites.first()
Step 5: Visualize#
# Visualize on a map
Map = geemap.Map()
vis_params = {
'min': 0,
'max': 1,
'palette': ['red', 'yellow', 'green']
}
# A palette can only be applied to a single band, so select one period (e.g. june)
Map.addLayer(composite.select('june'), vis_params, 'NDVI June')
Map.centerObject(roi, 10)
Map
Step 6: Create an Animated GIF#
# Generate an RGB GIF: one frame per year, using three periods as R, G, B.
# The frame rate (10 fps) and dimensions are set internally.
ndvi_processor.get_gif(
name='ndvi.gif',
bands=['march', 'june', 'september'] # [R, G, B] periods
)
Complete Example#
Here’s a complete working example:
import ee
import geemap
from ndvi2gif import NdviSeasonality
# Initialize
ee.Initialize(project='your-project-id')
# Define ROI (small area near Madrid, Spain).
# Kept small on purpose so the direct GeoTIFF download below stays under
# Earth Engine's ~50 MB synchronous limit — see "Export as GeoTIFF".
roi = ee.Geometry.Rectangle([-3.74, 40.38, -3.67, 40.45])
# Create processor
ndvi = NdviSeasonality(
roi=roi,
sat='S2',
periods=12,
start_year=2023,
end_year=2024,
index='ndvi',
key='median'
)
# Get the yearly composites (ee.ImageCollection, one image per year)
composites = ndvi.get_year_composite()
# Create an RGB GIF (one frame per year)
ndvi.get_gif(name='madrid_ndvi.gif', bands=['march', 'june', 'september'])
print("✓ Analysis complete! Check your GIF file.")
Understanding the Parameters#
sat - Satellite Sensor#
'S2'- Sentinel-2 (10m, 5-day revisit)'S1'- Sentinel-1 SAR (10m, 6-12 day revisit)'Landsat'- Landsat 4-9 merged (30m, 16-day revisit)'MODIS'- MODIS (500m, daily)'S3'- Sentinel-3 OLCI (300m)'ERA5'- ERA5-Land climate reanalysis (~11km, daily)'CHIRPS'- CHIRPS precipitation (~5.5km, daily)
periods - Temporal Resolution#
4- Seasonal (Winter, Spring, Summer, Fall)12- Monthly24- Bi-monthlyCustom numbers for specific applications
key - Statistical Method#
'median'- Robust to outliers (recommended for optical)'max'- Maximum value (good for vegetation indices)'mean'- Average value'percentile'- Custom percentile (specify withpercentileparameter)
index - Spectral Index#
'ndvi'- Vegetation health'evi'- Enhanced vegetation index'ndwi'- Water content'ndmi'- Moisture stressMany more! See Indices Reference
Export Options#
Export as GeoTIFF#
# Export every year's composite as a GeoTIFF to the current directory.
# Filenames are generated automatically as {sat}_{index}_{key}_{year}.tif
ndvi.get_export(scale=10)
⚠️ Size limit.
get_export()downloads directly from Earth Engine, which caps each synchronous request at ~50 MB. A large ROI, many periods (periods=12/24), or a finescalecan easily exceed it and raiseTotal request size ... must be less than or equal to 50331648 bytes. When that happens, either coarsen the export (ndvi.get_export(scale=30)), shrink the ROI, or export asynchronously to Google Drive (see Export to Google Drive below), which runs as a background task with a far larger budget.
Export to Google Drive#
# Export directly to Google Drive
ndvi.export_to_drive(
image=composite,
description='ndvi_madrid_2023',
folder='earthengine_exports',
scale=10
)
Common Patterns#
Multi-Year Analysis#
# Analyze multiple years
ndvi = NdviSeasonality(
roi=roi,
sat='S2',
periods=12,
start_year=2020,
end_year=2024,
index='ndvi'
)
# Get the yearly composites (one image per year)
composites = ndvi.get_year_composite()
# Thanks to the band-based design, cross-year seasonal queries are one line.
# For example, the maximum June NDVI across all years:
june_max = composites.select('june').max()
High Temporal Resolution#
# Bi-monthly for detailed monitoring
ndvi = NdviSeasonality(
roi=roi,
sat='S2',
periods=24, # Every 15 days
start_year=2024,
end_year=2024,
index='ndvi'
)
Using Percentiles#
# Use 85th percentile for cloud contamination
ndvi = NdviSeasonality(
roi=roi,
sat='S2',
periods=12,
start_year=2023,
end_year=2024,
index='ndvi',
key='percentile',
percentile=85
)
Next Steps#
Now that you understand the basics, explore:
ROI Options - Learn all the ways to define your study area
Indices Reference - Explore 40+ available indices
Tips & Tricks#
Start small: Test with small ROIs and short time periods first
Use median for optical: It’s more robust to clouds
Percentiles are flexible: Try 75th, 85th, or 95th percentiles
SAR uses mean: For Sentinel-1, use
key='mean'Check your projection: ROIs work best in EPSG:4326 (WGS84)