Shaun Levick https://www.geospatialecology.com

Environmental Monitoring and Modelling

Lab 6 - Monitoring vegetation condition in Google Earth Engine


Objective

The objective of this tutorial is to develop the skills for assessing change in vegetation condition over time. How do we know if an ecosystem is stressed or has been disturbed? Quantifying changes and attributing causality can be challenging - particularly in ecosystems that have large degrees of intra-annual variability.

One approach we have at out disposal is to compare attributes from recent years to those from a baseline period. In this lab we will explore anomalies in vegetation condition (measured in terms of EVI) to determine if condition is increasing or decreasing over time.


Acknowledgments

  • Google Earth Engine Team
  • Geospatial Analysis Lab, University of San Francisco (especially Nicholas Clinton and David Saah)
  • USAID, SERVER Mekong, NASA, Winrock International, adpc

Large scale vegetation condition monitoring

Getting to know MODIS and EVI

  • Start a new script by opening the code editor
  • Load the MODIS/MYD13A1 image collection and select the EVI band. EVI is an acronym for "Enhanced Vegetation Index". It is very similar to NDVI, but is more reliable in tropical ecosystems as it does not saturate as early as NDVI.
//Import the MODIS image collection MOD13A1 V6
 var collection = ee.ImageCollection('MODIS/006/MOD13A1').select('EVI');
  • Create a reference dataset by filtering for the dates from 2000 – 2010.
// Choose a reference period for your baseline
var reference = collection.filterDate('2001-01-01', '2010-12-31')
  .sort('system:time_start');
  • Compute the mean of the data series.
//Compute the mean EVI for the reference time frame
 var mean = reference.mean();
  • Display the mean using the code below. Chose appropriate values for min and max.
//Define visualisation parameters for EVI
var vis = {min: 2000, max: 5000, palette: ['brown','yellow','green']};
// Map EVI spatially
Map.addLayer(mean, vis, 'Reference EVI');

Use the inspector the check the appropriate range of values, then min and max in the example above with the values you discover.

  • Create a new image collection for the period 2011 – 2018. Give this image collection the name "recent".
//Create a collection of images that represent more recent conditions
 var recent = collection.filterDate('2011-01-01', '2018-12-31');
 // Calculate recent mean
 var meanRecent = recent.mean();
 // Map EVI spatially for recent years
 Map.addLayer(meanRecent, vis, 'Recent EVI');
  • Calculate and define anomalies (departure from long-term average) by subtracting the reference mean from the more recent time-series
//Define a function to subtract the reference mean
var subtractmean = function(image) {
  return image.subtract(mean).copyProperties(image, ['system:time_start']);
};

//Create a variable called anomalies by mapping the subtract mean over the recent time-series
var anomalies = recent.map(subtractmean);
  • Map the anomalies spatially using the code below.
//Map the cumulative anomalies by summing them
Map.addLayer(anomalies.sum(), {
  min: -10000,
  max: 10000,
  palette: [
    'darkred','red','yellow','green','darkgreen'
  ]}, 'Cumulative anomaly');

Use the inspector the check the appropriate range of values, then replace min and max in the example above with the values you discover.

Charting changes over time

Next we will chart the change of EVI through time, using the EVI anomalies to do so. We calculate the cumulative EVI for a specific area using the iterate function, then graph the cumulative anomaly (vertical axis) over time.

  • Get the timestamp from the most earliest image in the reference collection.
//Get timestamp of first image
var time0 = reference.first().get('system:time_start');
  • Create a list that contains a single image of zeros, with time of time0. Rename it 'EVI' to match the other images in the series.
//Create and empty list (zeros) list to provide a structure into which the EVI anomalies can be mapped
var first = ee.List([
  ee.Image(0).set('system:time_start', time0).rename('EVI')
]);
  • Paste the following code into the code editor to iterate through time.
//Use a function to iterate through time and accumulate the anomalies
var accumulate = function(image, list) {
  var previous = ee.Image(ee.List(list).get(-1));
  var added = image.add(previous)
    .set('system:time_start', image.get('system:time_start'));
  return ee.List(list).add(added);
};
  • Paste the code below in the code editor to run the iterate function.
//Run the iteration
var cumulative = ee.ImageCollection(ee.List(
  anomalies.iterate(accumulate, first)
));
  • Create a vector geometry using the rectangle polygon tool, and rename it "roi."
//Centre map on roi and specify zoom range (1-22)
Map.centerObject(roi, 7);
  • Prepare parameters to be used to make the chart.
//Define chart parameters
var chartParam = {
 title: 'Cumulative EVI anomaly over time',
  hAxis: {title: 'Time'},
  vAxis: {title: 'Cumulative EVI anomaly'},
};
  • Make a chart of the mean cumulative anomaly in the roi using the code below:
//Plot the chart
var chart = ui.Chart.image.seriesByRegion({
  imageCollection: cumulative,
  regions: roi,
  reducer: ee.Reducer.mean(),
  band: 'EVI',
  scale: 500,
  xProperty: 'system:time_start',
  seriesProperty: 'PROJECT'
});
//Print chart to console
print(chart.setOptions(chartParam));

Exercise

  • Think about how you can adapt this approach to other types of data, such as Land Surface Temperature or rainfall for example.


GEARS - Geospatial Ecology and Remote Sensing - https://www.geospatialecology.com