Google Earth Engine – Creating Time Series Chart

google-earth-engine

I'm facing an error in my code when I try to generate time series chart.
Anytime I run the code I get this error :

Error generating chart: No features contain non-null values of
"system:time_start"

I have seen post here which suggests to add this code to the function:

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

but it didn't function (I changed the collection into the name of the image collection I have but it didn't work).

here is the code I have :

/**
 * Function to mask clouds using the Sentinel-2 QA band
 * @param {ee.Image} image Sentinel-2 image
 * @return {ee.Image} cloud masked Sentinel-2 image
 */
function maskS2clouds(image) {
  var qa = image.select('QA60');

  // Bits 10 and 11 are clouds and cirrus, respectively.
  var cloudBitMask = 1 << 10;
  var cirrusBitMask = 1 << 11;

  // Both flags should be set to zero, indicating clear conditions.
  var mask = qa.bitwiseAnd(cloudBitMask).eq(0)
      .and(qa.bitwiseAnd(cirrusBitMask).eq(0));

  return image.updateMask(mask).divide(10000);
}

// Map the function over one year of data and take the median.
// Load Sentinel-2 TOA reflectance data.
var dataset = ee.ImageCollection('COPERNICUS/S2')
                  .filterDate('2015-06-23', '2019-07-02')
                  // Pre-filter to get less cloudy granules.
                  .filter(ee.Filter.lt('CLOUDY_PIXEL_PERCENTAGE', 20))
                  .select('B2','B3','B4','B8','QA60')
                  .filterBounds(geometry)
                  .map(maskS2clouds);

var rgbVis = {
  min: 0.0,
  max: 0.3,
  bands: ['B4', 'B3', 'B2'],
};

var clippedCol=dataset.map(function(im){ 
   return im.clip(geometry);
});

//test if clipping the image collection worked
Map.centerObject(geometry);
Map.addLayer(clippedCol.median(), rgbVis, 'RGB');

// Get the number of images.
var count = dataset.size();
print('Count: ',count);
// print(clippedCol);//here I get the error messege "collection query aborted after accumulation over 5000 elements
// print(dataset,'dataset');//the same error here


//function to calculate NDVI
var addNDVI = function(image) {
  var ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI');
  return image.addBands(ndvi);

};

//NDVI to the clipped image collection
var withNDVI = clippedCol.map(addNDVI);



// // Test the addNDVI function on a single image.
// var ndvi1 = withNDVI.select('NDVI').mean();


var colorizedVis = {
  min: 0.0,
  max: 1.0,
  palette: [
    'FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718', '74A901',
    '66A000', '529400', '3E8601', '207401', '056201', '004C00', '023B01',
    '012E01', '011D01', '011301'
  ],
};

// Test the addNDVI function on a single image.

// var ndvi1 = withNDVI.select('first').mean();
// var ndvi2 = withNDVI.select('second').mean();  

Map.centerObject(geometry);
print(withNDVI,'NDVI Images');
// Map.addLayer(ndvi1,colorizedVis,'test1');
// Map.addLayer(ndvi2,colorizedVis,'test2');



//Long-Term Time Series
var NDVIalltimes = Chart.image.seriesByRegion(withNDVI,geometry, ee.Reducer.mean(),'NDVI',
30, 'system:time_start').setOptions({
title: 'NDVI for Royal Exchange',
vAxis: {title: 'NDVI'},
});
print(NDVIalltimes);

The end goal is to get chart that shows the mean NDVI value for each Image in the image collection.

Best Answer

The reason for this error is that every image in withNDVI collection does not have system:time_start property. This is normal when you create image with normalizedDifference.

To fix this, simply add copyProperties to the first line in your addNDVI function:

var ndvi = image.normalizedDifference(['B8', 'B4'])
  .rename('NDVI')
  .copyProperties(image, ['system:time_start'])

And to the last line in your maskS2clouds function:

return image.updateMask(mask).divide(10000)
  .copyProperties(image, ['system:time_start']);

Also, it is recommended to use ui.Chart.image.seriesByRegion instead of Chart.image.seriesByRegion as the later would be removed sooner or later.

Related Question