Skip to content

GEE Python & JavaScript API

Control Google Earth Engine from your Python scripts — automate satellite analysis, export results, and build workflows.


Provider
Google LLC
Python Package
pip install earthengine-api geemap
Access Level
🟡 GEE Account Required (free for research)
Use Case
Automated satellite analysis, time-series, export
Free Tier
Generous — no cost for academic/personal use

Installation & Setup

# Install in your virtual environment (bookenv)
pip install earthengine-api geemap

First-Time Authentication

import ee

# Authenticate — opens browser, asks you to log in to your Google account
ee.Authenticate()

# Initialize with your GEE project (create one at console.cloud.google.com)
ee.Initialize(project='your-gee-project-id')

print("GEE initialized successfully!")
print(f"GEE Python API version: {ee.__version__}")

Core GEE Python Concepts

Working with Images

import ee
ee.Initialize(project='your-project')

# Load a single Sentinel-2 image (by ID)
img = ee.Image("COPERNICUS/S2_SR_HARMONIZED/20231201T054139_20231201T054643_T43QFE")

# Get image info
print(img.bandNames().getInfo())  # ['B1', 'B2', 'B3', ...]
print(img.projection().getInfo())  # EPSG code

# Calculate NDVI
ndvi = img.normalizedDifference(['B8', 'B4']).rename('NDVI')

Working with ImageCollections

# Load Sentinel-2 collection, filter, composite
s2 = (ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
        .filterDate('2023-11-01', '2024-02-28')
        .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 15))
        .filterBounds(ee.Geometry.Rectangle([72.6, 18.5, 80.9, 22.1]))  # Maharashtra
        .median())  # Cloud-free composite by taking median pixel

print(f"Composite info: {s2.bandNames().getInfo()}")

Exporting Results to Google Drive

# Calculate NDVI for Maharashtra and export
maharashtra = ee.Geometry.Rectangle([72.6, 15.6, 80.9, 22.1])

ndvi = s2.normalizedDifference(['B8', 'B4']).rename('NDVI').clip(maharashtra)

# Export to Google Drive (runs asynchronously in GEE)
task = ee.batch.Export.image.toDrive(
    image=ndvi,
    description='Maharashtra_NDVI_2024',
    folder='GEE_Exports',
    fileNamePrefix='mh_ndvi_2024',
    region=maharashtra,
    scale=100,          # 100m resolution (reduces file size)
    maxPixels=1e10,
    fileFormat='GeoTIFF'
)
task.start()
print(f"Export task started: {task.id}")
print("Check status at: https://code.earthengine.google.com/tasks")

Zonal Statistics (Reduce by District)

# Compute mean NDVI for each district in Maharashtra
districts = ee.FeatureCollection("FAO/GAUL/2015/level2") \
               .filter(ee.Filter.eq('ADM1_NAME', 'Maharashtra'))

def add_ndvi(feature):
    mean_val = ndvi.reduceRegion(
        reducer=ee.Reducer.mean(),
        geometry=feature.geometry(),
        scale=100,
        maxPixels=1e9
    ).get('NDVI')
    return feature.set('mean_NDVI', mean_val)

districts_with_ndvi = districts.map(add_ndvi)

# Download as DataFrame
import geemap
df = geemap.ee_to_df(districts_with_ndvi, columns=['ADM2_NAME', 'mean_NDVI'])
print(df.sort_values('mean_NDVI', ascending=False))

Interactive Maps with geemap (Jupyter)

import geemap
import ee
ee.Initialize(project='your-project')

# Create interactive map
Map = geemap.Map(center=[19.5, 75], zoom=7)

# Add Sentinel-2 true colour
s2_mh = (ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
           .filterBounds(ee.Geometry.Rectangle([72.6, 15.6, 80.9, 22.1]))
           .filterDate('2023-11-01', '2024-02-28')
           .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 10))
           .median())

Map.addLayer(s2_mh,
             {'bands': ['B4', 'B3', 'B2'], 'min': 0, 'max': 3000},
             'Sentinel-2 Maharashtra')

# Add NDVI layer
ndvi = s2_mh.normalizedDifference(['B8', 'B4'])
Map.addLayer(ndvi,
             {'min': -0.1, 'max': 0.8, 'palette': ['brown', 'yellow', 'green', 'darkgreen']},
             'NDVI')

Map  # Display in Jupyter cell

✏️ Practice Exercise

Exercise 6.2 — NDVI Change Detection 2018 vs 2023

Goal: Find areas in your district where vegetation has improved or declined.

import ee, geemap
ee.Initialize(project='your-project')

district = ee.Geometry.Rectangle([73.7, 18.3, 74.5, 18.8])  # Pune — change this

def get_ndvi(year):
    return (ee.ImageCollection("COPERNICUS/S2_SR_HARMONIZED")
              .filterBounds(district)
              .filter(ee.Filter.calendarRange(year, year, 'year'))
              .filter(ee.Filter.calendarRange(11, 12, 'month'))  # Nov-Dec
              .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
              .median()
              .normalizedDifference(['B8', 'B4'])
              .rename('NDVI'))

ndvi_2018 = get_ndvi(2018)
ndvi_2023 = get_ndvi(2023)
change = ndvi_2023.subtract(ndvi_2018).rename('NDVI_Change')

Map = geemap.Map()
Map.centerObject(district, 11)
Map.addLayer(change, {'min': -0.3, 'max': 0.3, 'palette': ['red','white','green']},
             'NDVI Change 2018→2023')
Map
  • Red = vegetation declined (possible deforestation or urbanisation)
  • Green = vegetation improved (reforestation, new crops)
  • Are there large red patches near your city boundary? (urban expansion)
  • Are there green patches in forest areas? (forest recovery)

Next: AI Kosh (CDAC) →