1

I am trying to calculate monthly average NDVI for Ukraine the 2010-2020 period using MODIS data and then plot the values onto a graph (averaging all images in each individual month of each year separately across the full period). You can see the code I am using below. However, I keep getting the following error: enter image description here

From checking the GEE documentation, I assumed this was an casting issue and have fixed those issues so I am not sure why the code is still failing.

//calculate average monthly NDVI for Ukraine
//get MODIS NDVI
var collection = ee.ImageCollection('MODIS/006/MOD13A1').select('NDVI');

//import country boundaries
var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');

//Subset Ukraine feature from countries.
var ukr = ee.Feature(
  countries
   .filter(ee.Filter.eq('country_na', 'Ukraine'))
    .first()
);

// Choose a reference period for your baseline
var reference = ee.ImageCollection(collection.filterDate('2010-01-01', '2020-12-31'))
  .sort('system:time_start');
  
//function to calculate monthly mean
//Get timestamp of first image
var time0 = ee.Image(reference.first().get('system:time_start'));

//Create an empty list (zeros) list to provide a structure into which the NDVI anomalies can be mapped
var first = ee.List([
  ee.Image(0).set('system:time_start', time0).rename('NDVI')
]);

//Use a function to iterate through months and calculate average NDVI
var months = ee.List.sequence(1, 12);
var byMonth = ee.ImageCollection.fromImages(
      months.map(function (m) {
        return ee.Image(reference.filter(ee.Filter.calendarRange(m, m, 'month')))
                    .select(1).mean()
                    .set('month', m);
}));

//Run the iteration
var average = ee.ImageCollection(ee.List(
  reference.iterate(byMonth, first)
));

//Define chart parameters
var chartParam = {
 title: 'Monthly average NDVI',
  hAxis: {title: 'Time'},
  vAxis: {title: 'Average NDVI'},
};

//Plot the chart
var chart = ui.Chart.image.seriesByRegion({
  imageCollection: average,
  regions: ukr,
  reducer: ee.Reducer.mean(),
  scale: 500,
  xProperty: 'system:time_start',
  seriesProperty: 'PROJECT'
});
//Print chart to console
print(chart.setOptions(chartParam));    


1 Answer 1

2

Looks like you were pretty close, and with the help of Nicholas Clinton's answer here we can arrive at a solution. The main changes I made were:

  1. removing unnecessary variable definitions (first and time0)
  2. adjust how the function mapped to months is defined
  3. added a years variable for the same function mapping technique

All of that said, here's an updated script.

//calculate average monthly NDVI for Ukraine
//get MODIS NDVI
var collection = ee.ImageCollection('MODIS/006/MOD13A1').select('NDVI');

//import country boundaries
var countries = ee.FeatureCollection('USDOS/LSIB_SIMPLE/2017');

//Subset Ukraine feature from countries.
var ukr = ee.Feature(
  countries
   .filter(ee.Filter.eq('country_na', 'Ukraine'))
    .first()
);
print("ukr",ukr);

//Use a function to iterate through months and calculate average NDVI
var months = ee.List.sequence(1, 12);
print("months",months);
var years = ee.List.sequence(2010, 2020);
print("years",years);

// Map filtering and reducing across year-month combinations and convert to ImageCollection
var yrMo = ee.ImageCollection.fromImages(
  years.map(function (y) {
        return months.map(function (m) {
            return collection
              .filter(ee.Filter.calendarRange(y, y, 'year'))
              .filter(ee.Filter.calendarRange(m, m, 'month'))
              .mean()
              .set('year',y)
              .set('month',m);
        });
    }).flatten());
print("yrMo",yrMo);

//Define chart parameters
var chartParam = {
 title: 'Monthly average NDVI',
  hAxis: {title: 'Time'},
  vAxis: {title: 'Average NDVI'},
};

//Plot the chart
var chart = ui.Chart.image.seriesByRegion({
  imageCollection: yrMo,
  regions: ukr,
  reducer: ee.Reducer.mean(),
  scale: 500,
  xProperty: 'system:index',
  seriesProperty: 'PROJECT'
});
//Print chart to console
print(chart.setOptions(chartParam));
2
  • Thank you, this works very well to calculate monthly averages. However, I am trying to create a plot showing the monthly averages for each individual month in each year in the full 2010-2020 period (132 months in total), and then I will be looking at calculating seasonal averages (averages for 3 month periods) across this same time period
    – Simba06
    Feb 11, 2021 at 20:20
  • Got it. See the revised answer above. Feb 12, 2021 at 22:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.