I have script that does the enxt procedures:

  1. create imagecollection from Landsat7
  2. clip the images according to specific geometry and calculte NDVI for each one
  3. filter the rasters according to the number of pixels (I don't want to have small rasters)
  4. creates images by calculte for each year the mean NDVI value.
  5. Creates timeseries graph based on years.

Now I want to create the 6th step which is to calculte for each raster how many pixels got NDVI value greater than 3. because I have one image per year I want to create a for loop that will count those pixels for each year and will produce a table. I have written a code but it is not good because it seems like javascript doesn't understand that "i" is image. also, I don't think this code will prosuce a table in the end.

This is my code:

// Declare years of interest
var years = ee.List.sequence(2000, 2013);

// Map a function to select data within the year and apply mean reducer
var byYear = ee.ImageCollection.fromImages(
    years.map(function(y) {
      return filter
        .filter(ee.Filter.calendarRange(y, y, 'year'))
        .set('year', y);

var listOfImages =(byYear.toList(byYear.size()));

for (var i in listOfImages) {
  var gt03 = i.gt(0.3).selfMask().rename('NDVI_gt03');
  //count the number of total pixels
  var c03 = gt03.reduceRegion({
  reducer: ee.Reducer.count(),
  geometry: geometry,
  crs: 'EPSG:4326',
  scale: 30,


The wrror message:

i.gt is not a function

*I don't understand this error, because this code works when I do it on one image so why here it can't?

*maybe instead of lop I should use function? then what is the differences between them?

My end goal: To get a table or any calculation which shows for each year the number of pixels that were found in my raster with value higher than 0.3

  • Can you provide a working example for us? Perhaps the answers given already on this forum might help you a bit? gis.stackexchange.com/questions/342882/…
    – Jobbo90
    Commented Nov 25, 2019 at 11:40
  • The given code is not working, gives error: "filter" is not defined in this scope. Please provide the GEE link for your code for replicating your error
    – shahryar
    Commented Nov 25, 2019 at 16:09

1 Answer 1


I suggest you always include a link to a working EE script when posting a question. It makes it easier to help you. You're trying to do something like this, right?

var listOfImages = years.map(function(y) {
  y = ee.Number(y)
  var image = collection
      ee.Date.fromYMD(y, 1, 1), 
      ee.Date.fromYMD(y.add(1), 1, 1)
    .reduce(ee.Reducer.mean()) // .median() might be better here...
    .select(['B3.*', 'B4.*'], ['B3', 'B4'])
  var ndvi = image
    .normalizedDifference(['B3', 'B4'])
  return ndvi
    .set('year', y);

var counts = listOfImages.iterate(function (image, acc) {
  image = ee.Image(image)
  acc = ee.FeatureCollection(acc)
  var count = image.reduceRegion({
    reducer: ee.Reducer.count(),
    geometry: geometry,
    crs: 'EPSG:4326',
    scale: 30,
  return acc.merge(ee.FeatureCollection([
    ee.Feature(null, {year: image.get('year'), count: count})
}, ee.FeatureCollection([]))

var chart = ui.Chart.feature.byFeature(counts, 'year', 'count')


You should be careful when using client-side looping in your scripts - unless you really know what you're doing. Using EE functions like map() and iterate() is usually the right thing to do.

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.