4

I have a ndvi series which I am able to plot using below code:

var ndvi = l8.map(function(image) {
  return image.select().addBands(image.normalizedDifference(['B5', 'B4']));
});
var ndviChart = ui.Chart.image.series(ndvi, point, ee.Reducer.mean(), 500);
print(ndviChart);

My goal is to calculate the average ndvi for every 3 months window and then calculate the maximum ndvi over that 3 months window. How to access data in ui.Chart.series and is there any way by which I can do the above calculation on Google server ?

In javascript it can be done using

<script>
var lista = [22,4,5,6,11];
var maxAvg = 0.0;
for (var i = 0; i < lista.length - 2; i++) {
var avg = 0.0;
for (var j = 0; j < 3; j++) {
   avg = avg + lista[i+j];
}
if (maxAvg < (avg/3.0)) {maxAvg = (avg/3.0)};

}

document.write(maxAvg);
</script>

I want to replace lista with ndviChart series. Can anybody help me in this direction?

Kersten
  • 9,899
  • 3
  • 37
  • 59
rombi
  • 63
  • 1
  • 5

2 Answers2

4

You might need some cloud masking in there, too, but here's the three-monthly part. Also note that the output imagery has three bands: mean, min, and max. You can now use that collection to make a chart, export a table, etc.

var ndvi = ee.ImageCollection('LANDSAT/LC08/C01/T1_SR').map(function(image) {
  return image.select().addBands(image.normalizedDifference(['B5', 'B4']));
});

/* Creates a collection of mosaics with a given temporal interval.
 *
 * collection - the collection from which to make composites.
 * start - the date of the first composite (either a string or an ee.Date)
 * count - the number of composites to make
 * interval - The time between composites, in units of "units".
 * units - The units of step (day, week, month, year; see ee ee.Date.advance)
 */
var temporalCollection = function(collection, start, count, interval, units) {
  // Create a sequence of numbers, one for each time interval.
  var sequence = ee.List.sequence(0, ee.Number(count).subtract(1));

  var originalStartDate = ee.Date(start);

  return ee.ImageCollection(sequence.map(function(i) {
    // Get the start date of the current sequence.
    var startDate = originalStartDate.advance(ee.Number(interval).multiply(i), units);

    // Get the end date of the current sequence.
    var endDate = originalStartDate.advance(
      ee.Number(interval).multiply(ee.Number(i).add(1)), units);

    return collection.filterDate(startDate, endDate)
        .reduce(ee.Reducer.mean().combine({
          reducer2: ee.Reducer.minMax(),
          sharedInputs: true
        }));
  }));
};

var threeMonthlyNDVI = temporalCollection(ndvi, ee.Date('2015-01-01'), 12, 3, 'month');

var check = ee.Image(threeMonthlyNDVI.first());
Map.addLayer(check, {bands: 'nd_mean', min: 0, max: 1}, 'check')
csheth
  • 664
  • 1
  • 8
  • 22
Nicholas Clinton
  • 4,339
  • 16
  • 22
2

I took a similar approach to Nicholas. Here, i'm just computing my windows based on start and end date.


// assuming you have the start and end date
var startDate = ee.Date('2017-01-01');
var endDate = ee.Date('2018-01-01');
// this is the window size in months
var window = 3;
// just calculating number of windows so that i can map over it
// i could go for iterate with a break condition but i prefer map
// as i can compute parallelly 
var numberOfWindows = endDate.difference(startDate,'month').divide(window).toInt();
// generating a sequence that can be used as an indicator for my window step
var sequence = ee.List.sequence(0, numberOfWindows); 
// inclusive series so the number of windows will be correct

// mapping over the sequence
sequence = sequence.map(function(num){
  // just casting element of sequence to a number object
  num = ee.Number(num);
  // finding the start and end point of my windows
  var windowStart = startDate.advance(num.multiply(window), 'month');
  var windowEnd = startDate.advance(num.add(1).multiply(window), 'month');
  // selecting images that fall within those windows
  var subset = ndvi.filterDate(windowStart,windowEnd);
  // calculating the mean ndvi of that window
  return subset.mean().set('system:time_start',windowStart);
});

// converting list of mean images to imagecollection 
var composites = ee.ImageCollection.fromImages(sequence);

// calculating the max image among those 3 month composites
var max = composites.max();

// displaying the layers
print(sequence,max);
Map.addLayer(max);

As for plotting the graph this is basically what you want to do.

// plotting graph of original and smoothened data for band 1
// in a specific point
print(ui.Chart.image.series(
  composites.select(['nd']), geometry, ee.Reducer.mean(), 30)
    .setSeriesNames(['3monthly-mean-ndvi'])
    .setOptions({
      title: '3monthly-mean-ndvi',
      lineWidth: 1,
      pointSize: 3,
}));

All the calculation here is done in the google servers. You can explore the code here https://code.earthengine.google.com/ec245a4eb0e89b7c1a58eaff01bda5f3

Nishanta Khanal
  • 1,633
  • 9
  • 12