TransWikia.com

Finding monthly NDVI anomalies in Google Earth Engine?

Geographic Information Systems Asked by astokes on August 29, 2021

I am using 16 NDVI data from GIMMS 3rd generation, and I wish to somehow visualize monthly anomalies (Difference from long term means greater than .5). I have plotted a time series of the data running from 1981 to 2013 and have also made dictionaries matching the long term monthly means and standard deviations with each month in a key value pair.

I am struggling with making a new collection with only the anomalies.

I have listed the code I have below

I am brand new to GEE.

Code:

var NDVI = NDVI.select("ndvi");
print("NDVI", NDVI)
var plotNDVI = ui.Chart.image.seriesByRegion(NDVI, county,ee.Reducer.mean(),
'ndvi',500,'system:time_start', 'system:index')
              .setChartType('LineChart').setOptions({
                title: 'NDVI time series',
                hAxis: {title: 'Date'},
                vAxis: {title: 'NDVI'}
});
print("Plot", plotNDVI);

//finding monthly means to classify anomalies
var month = ee.List.sequence(1,12,1);
var bymonth = ee.ImageCollection.fromImages(
      month.map(function (m) {
        return NDVI.filter(ee.Filter.calendarRange(m,m,'month'))
                    .mean()
                    .set('month', m)}));

var months_image = bymonth.toBands();

var month_mean = months_image.reduceRegions({
      collection: county,  // the region over which values are sumamrized
      reducer: ee.Reducer.mean(),  // the summary statistic 
      scale:1000 });

print(month_mean.first(), "Means");

//finding monthly standard deviations to classify anomalies
var month = ee.List.sequence(1,12,1);
var bymonth = ee.ImageCollection.fromImages(
      month.map(function (m) {
        return NDVI.filter(ee.Filter.calendarRange(m,m,'month'))
                    .mean()
                    .set('month', m)}));

var months_image = bymonth.toBands();

var month_sd = months_image.reduceRegions({
      collection: county,  // the region over which values are sumamrized
      reducer: ee.Reducer.stdDev(),  // the summary statistic 
      scale:1000 });

print(month_sd.first(), "Standard Deviations");

//Grouping NDVI data into monthly
var months = ee.List.sequence(1, 12);
var years = ee.List.sequence(1982, 2017);

var byMonthYear = ee.ImageCollection.fromImages(
  years.map(function(y) {
    return months.map(function (m) {
      return NDVI
        .filter(ee.Filter.calendarRange(y, y, 'year'))
        .filter(ee.Filter.calendarRange(m, m, 'month'))
        .mean()
        .set('month', m).set('year', y)
        ;
  });
}).flatten());
print(NDVI.filter(ee.Filter.calendarRange(1990,1990,'year')).filter(ee.Filter.calendarRange(2,2,'month'))
.first().get('system:time_start'));
print(byMonthYear, "ByMonthYear");

//creating key value pairs between means and months
var means = ee.List([0.43123850243534323,0.3894521339616539,0.3678471519772741,0.41706308918022134,
0.46037764309919055,0.38888842454396205,0.33842364610048087,0.33794841210007037,0.3474507272535538,
0.34690699156315224,0.42128687629206923,0.4702649273882262]);
var months = ee.List(['1','2','3','4','5','6','7','8','9','10','11','12']);
var sd = ee.List([0.13979703874247837, 0.13734823987549263, 0.12584764519807798
,0.11915726272137396,0.12764610950234742,0.1277199807141862,0.11686175416658554
,0.11974156118004246,0.12617018760624113,0.11915693592123006,0.12497756240202171,0.13854867546056848])

var monthmonths = ee.Dictionary.fromLists(months, month);
var monthmeans = ee.Dictionary.fromLists(months, means);
var monthsd = ee.Dictionary.fromLists(months, sd);
print("month means", monthmeans);
print("month sd", monthsd);

//var plotNDVI = ui.Chart.image.seriesByRegion(byMonthYear, county,ee.Reducer.mean(),
//'ndvi',500,'system:time_start','system:index')
  //            .setChartType('LineChart').setOptions({
    //            title: 'NDVI time series',
      //          hAxis: {title: 'Date'},
        //        vAxis: {title: 'NDVI'}
//});
//print("Plot", plotNDVI);

var meanAnomaly = ee.ImageCollection.fromImages(
  years.map(function(y) {
    return months.map(function (m) {
      return NDVI
        .filter(ee.Filter.calendarRange(y, y, 'year'))
        .filter(ee.Filter.calendarRange(m, m, 'month'))
        .mean().subtract(monthmeans.getNumber(ee.String(m)))
        .set('month', m).set('year', y)
        ;
  });
}).flatten());
print("mean anomaly", meanAnomaly)

One Answer

I think there are two issues here. First and more important one being, you are trying to calculate anomalies for year 1982 to 2017 but the collection you are using GIMMS 3rd generation (NASA/GIMMS/3GV0) has data only upto 2013. So you can not run it till 2017. Another issue is that when you use ee.Filter.calendarRange it requires numbers for start month and end month but since your months variable was updated to contain strings for creating the dictionaries with mean and sds in this line

var months = ee.List(['1','2','3','4','5','6','7','8','9','10','11','12']);

There are now strings not numbers. So when u use months.map the passed elements in variable m are strings. This can be easily fixed by parsing the passed values within the mapping function.

var meanAnomaly = ee.ImageCollection.fromImages(
  years.map(function(y) {
    return months.map(function (m) {
      m = ee.Number.parse(m)
      return NDVI
        .filter(ee.Filter.calendarRange(y, y, 'year'))
        .filter(ee.Filter.calendarRange(m, m, 'month'))
        .mean().subtract(monthmeans.getNumber(ee.String(m)))
        .set('month', m).set('year', y)
        ;
  });
}).flatten());
print("mean anomaly", meanAnomaly)

You can see a working link here. Since your geometry was not available to me, I took the liberty of creating my own.

Answered by Nishanta Khanal on August 29, 2021

Add your own answers!

Ask a Question

Get help from others!

© 2024 TransWikia.com. All rights reserved. Sites we Love: PCI Database, UKBizDB, Menu Kuliner, Sharing RPP