Richter’s stained glass in Cologne Cathedral. Inspiration for this library.
Ndvi2Gif is a Python library designed to simplify access to global satellite data through the Google Earth Engine platform. While its name highlights the ability to create seasonal GIF animations, the true power of this tool lies in its capability to compute and export pixel-wise statistics for any region on Earth, across any time span covered by supported remote sensing datasets.
Built on top of Google Earth Engine and Geemap, it allows you to:
Whether you’re monitoring crop phenology, detecting harvest events, assessing drought trends, classifying land cover, or preparing input layers for further ecological modeling, ndvi2gif makes it easier to extract reliable, multi-temporal remote sensing information at scale.
Ndvi2Gif was updated and extended as part of its integration into the eLTER and SUMHAL projects, which also enabled the use of eLTER site boundaries (via deimsPy) as one of its input sources.

The 0.6.0 release transforms Ndvi2Gif into a complete remote sensing analysis platform with integrated machine learning capabilities, positioning it as a comprehensive solution for remote sensing workflows.
Unlike many visualization-oriented tools, Ndvi2Gif is designed as a remote sensing analytics suite that abstracts much of the complexity of working directly with Google Earth Engine, while giving you the flexibility to go far beyond GIF creation.
You can:
Perform nested aggregations:
First compute temporal summaries (e.g., per-season percentiles or means), then apply a second statistical reduction across years (e.g., median, min, max).
TimeSeriesAnalyzer:
S1ARDProcessor:
Target any ecological or phenological metric by choosing the appropriate index and analysis pipeline.
Work globally, without needing to download or preprocess raw satellite data — all computations are handled via Earth Engine’s cloud infrastructure.
In other words: if you can describe a temporal range, a spatial region, an index, and a chain of statistics — ndvi2gif can not only generate it, but now also help you classify, analyze and interpret the changes over time.
Yes, it makes nice GIFs — but it’s much more than that.
Crop pattern dance around Los Palacios y Villafranca (SW Spain) and the palette color combinations shown
| Input Type | Description | Example / Notes |
|---|---|---|
| Drawn Geometry | Use geemap to draw a polygon directly on a map | Works in Jupyter Notebooks |
| Shapefile / GeoJSON | Provide a file path to a vector dataset | EPSG:4326 recommended |
| eLTER site ID | Use deimsPy to fetch site boundaries by DEIMS ID |
e.g., deimsid:ab8278e6-0b71-4b36-a6d2-e8f34aa3df30 |
| Sentinel-2 Tile | Specify MGRS tile code (e.g., T30TYN) |
Automatically fetches tile geometry |
| Landsat Path/Row | Provide WRS-2 path and row codes (e.g., 198/034) |
Covers full Landsat archive |
from ndvi2gif import NdviSeasonality, LandCoverClassifier
# Create multi-temporal features
processor = NdviSeasonality(
roi='study_area.shp',
sat='S2',
periods=12,
start_year=2022,
end_year=2024
)
# Initialize classifier
classifier = LandCoverClassifier(processor)
# Create feature stack with multiple indices
features = classifier.create_feature_stack(
indices=['ndvi', 'evi', 'ndwi', 'ndre'],
include_statistics=True,
normalize=True
)
# Add training data
classifier.add_training_data('training_samples.shp')
# Classify with Random Forest
classification = classifier.classify_supervised('random_forest')
# Assess accuracy
classifier.assess_accuracy()
# Export results
processor.export_to_drive(
image=classification,
description="landcover_2024",
folder="classifications"
)
Sentinel:
Landsat (Surface Reflectance):
MODIS (Surface Reflectance):
You can combine any of the supported indices, datasets, and statistical methods. By default, the tool uses NDVI with the maximum statistic to avoid cloud contamination. However, median and custom percentiles are often visually better for Landsat datasets and specific applications.
Note: Sentinel-2 uses Surface Reflectance, Sentinel-3 uses Level-1B TOA radiance (optimized for aquatic applications), while Landsat and MODIS use Surface Reflectance (SR) for superior atmospheric correction and scientific quality.
The tool generates rasters with 4 (seasons), 12 (months), or 24 (custom periods) bands per year.
Beyond creating a nice-looking animated GIF, this multi-seasonal compositing method provides insights into vegetation dynamics, phenology, land cover, and more. High values in all seasons (white tones) typically mean perennial vegetation, while low values (dark tones) might represent water, soil, or impervious surfaces.
You can also export seasonal composites as GeoTIFF files for further analysis. Multi-year composites are supported as well. For example, you can export median NDVI per season for all of Africa between 2001–2020, bi-monthly VV/VH ratios for crop monitoring, or daily Sentinel-3 turbidity indices for water quality assessment.
Export any image or classification directly to your Google Drive:
processor.export_to_drive(
image=classified_map,
description="landcover_2023",
folder="ndvi2gif_results",
scale=30,
crs="EPSG:4326",
maxPixels=1e13
)
Save results as Earth Engine Assets for further processing:
processor.export_to_asset(
image=classification,
asset_id="users/yourname/landcover_2023",
pyramiding_policy={"class": "mode"},
overwrite=True
)
The library now automatically selects the appropriate scale based on the sensor:
You can install ndvi2gif using either pip or conda:
pip install ndvi2gif
conda install -c conda-forge ndvi2gif
We’re building a comprehensive Jupyter Book tutorial with step-by-step guides:
🌐 Visit the Tutorial Book (Work in Progress)
The tutorial includes:
Note: The tutorial is actively being developed. Core sections (Getting Started, Basic NDVI, FAQ) are complete, with more content being added regularly.
Check out our example notebooks:
More examples are regularly added to showcase new capabilities and use cases.
import ee
import geemap
from ndvi2gif import NdviSeasonality, TimeSeriesAnalyzer, LandCoverClassifier
# Authenticate Earth Engine
ee.Authenticate()
ee.Initialize()
# Basic NDVI analysis
ndvi_analysis = NdviSeasonality(
roi=your_roi, # Your region of interest
periods=12, # Monthly analysis
start_year=2023,
end_year=2024,
sat='S2', # Sentinel-2
key='percentile', # Use percentile statistic
percentile=85, # 85th percentile (flexible!)
index='ndvi'
)
# Generate composite
composite = ndvi_analysis.get_year_composite()
# Create animated GIF
ndvi_analysis.get_gif(name='ndvi_evolution.gif')
# NEW in v0.6.0: Land Cover Classification
classifier = LandCoverClassifier(ndvi_analysis)
# Create multi-index feature stack
features = classifier.create_feature_stack(
indices=['ndvi', 'evi', 'ndwi'],
normalize=True
)
# Add training data and classify
classifier.add_training_data('training_points.shp')
landcover = classifier.classify_supervised('random_forest')
# Export to Drive
ndvi_analysis.export_to_drive(
image=landcover,
description="classification_2024",
folder="results"
)
# Get feature importance
importance = classifier.get_feature_importance()
print(f"Most important features: {importance[:5]}")
# NEW: Sentinel-3 water quality monitoring
water_quality = NdviSeasonality(
roi=your_lake,
periods=24, # Bi-monthly for detailed monitoring
start_year=2023,
end_year=2024,
sat='S3', # Sentinel-3 OLCI
key='median',
index='turbidity' # Water turbidity assessment
)
# NEW: Daily algal bloom detection
algae_monitor = NdviSeasonality(
roi=your_water_body,
periods=12, # Monthly analysis
sat='S3', # Daily coverage with S3
index='floating_algae', # Specialized for bloom detection
key='mean',
start_year=2024,
end_year=2024
)
# Advanced: Sentinel-2 Red Edge analysis for precision agriculture
chlorophyll_analysis = NdviSeasonality(
roi=your_agricultural_field,
periods=24, # Bi-monthly for detailed monitoring
sat='S2', # Only S2 has Red Edge bands
index='ireci', # Highly sensitive to chlorophyll
key='median',
start_year=2023,
end_year=2024
)
# SAR-based crop monitoring with orbit control
sar_analysis = NdviSeasonality(
roi=your_roi,
periods=24, # Bi-monthly for detailed monitoring
start_year=2023,
end_year=2024,
sat='S1', # Sentinel-1 SAR
key='mean',
index='vv_vh_ratio', # Excellent for harvest detection
orbit='DESCENDING' # Use only descending orbits for consistency
)
# Cyanobacteria detection with NDCI
cyano_detection = NdviSeasonality(
roi=your_lake,
periods=12, # Monthly monitoring
sat='S2', # NDCI requires Red Edge
index='ndci', # Cyanobacteria detection
key='percentile',
percentile=75,
start_year=2023,
end_year=2024
)
#### TimeSeriesAnalyzer – trend and phenology ####
# Seasonal NDVI composites
ndvi = NdviSeasonality(
roi=your_roi,
sat='S2',
periods=12, # monthly
start_year=2018,
end_year=2024,
index='ndvi'
)
# Analyze temporal trends and phenology
ts = TimeSeriesAnalyzer(ndvi)
df = ts.extract_time_series()
trend = ts.analyze_trend(df)
ts.plot_comprehensive_analysis()
#### SAR Analysis ####
from ndvi2gif import S1ARDProcessor
import ee
ee.Initialize()
# Configure ARD processor with terrain correction + Refined Lee filter
s1 = S1ARDProcessor(
speckle_filter='REFINED_LEE',
terrain_correction=True,
terrain_flattening_model='VOLUME',
dem='COPERNICUS_30'
)
# Apply corrections to a Sentinel-1 image
image = ee.Image("COPERNICUS/S1_GRD/...") # replace with your image ID
processed = s1.apply_speckle_filter(s1.apply_terrain_correction(image))
For complete examples, see the [example notebooks](examples_notebooks/) folder.
🤖 Land Cover Classification (NEW in v0.6.0)
🌾 Agricultural Monitoring
🌊 Water Quality & Environmental Monitoring
🌍 Environmental Research
📊 Operational Applications
v0.6.0 ✅ Machine Learning & Classification Suite
Status: Released August 2025!
✅ LandCoverClassifier – Complete classification workflows
✅ Multiple ML Algorithms – RF, SVM, CART, K-means, and more
✅ Enhanced Exports – Google Drive and EE Assets
✅ 95%+ Documentation – Comprehensive docstrings with examples
✅ Feature Engineering – Multi-temporal stacks with normalization
v1.0.0 🎯 Complete Climate Analysis Platform
Status: Planned
📚 Jupyter Book – Interactive documentation and tutorials
🌡️ Climate Datasets – ERA5, CHIRPS, TerraClimate integration
🌍 Climate Analysis – Advanced climate change assessment tools
🔧 API Stability – Long-term support commitment
We welcome contributions from the community! Whether you’re a developer, researcher, or just curious about remote sensing, your input can help improve Ndvi2Gif.
🐛 Bug reports: GitHub Issues
💡 Feature requests: GitHub Discussions
🤝 Pull requests: Always welcome!
📚 Example contributions: Share your use cases in the examples_notebooks/ folder
JOSS Manuscript in preparation. For now, please cite this software as:
@software{garcia_diaz_ndvi2gif_2024,
author = {García Díaz, Diego},
title = {ndvi2gif: Multi-Seasonal Remote Sensing Analysis Suite},
url = {https://github.com/Digdgeo/Ndvi2Gif},
version = {0.6.0},
year = {2025}
}
This project is licensed under the MIT License - see the LICENSE.txt file for details.