2

I would like to take the data generated in the doySeries chart and use it as an array of values. Is this at all possible? What I am interested in is using the mean over the years to create a list of cumulative precipitation values that I can then use in another chart as a reference point to identify anomalous days in later years. Below is the script I have so far:

var polygon = ee.Geometry.Polygon([[-92.56227555674951,40.858223918075275],
                                   [-92.56227555674951,40.85666590660416],
                                   [-92.56227555674951,40.85666590660416],
                                   [-92.55961480540674,40.85828883442468]]);

var startDateEarly = ee.Date('1981-01-01');
var endDateEarly = ee.Date('1983-12-31');

var chirpsColl = ee.ImageCollection('UCSB-CHG/CHIRPS/DAILY')
                .filterDate(startDateEarly, endDateEarly)
                .filterBounds(polygon);

var chirpsMean = ui.Chart.image.doySeries({
  imageCollection: chirpsColl,
  region: polygon,
  scale: 1,
  yearReducer: ee.Reducer.mean(),
  //seriesProperty: 'label'
});
print(chirpsMean);

on a side note, is the scale a buffer? If so, if I set it to 0, will it only reduce within my selected region?

  • 1
    Scale is not a buffer. You can read about EE scale here: developers.google.com/earth-engine/scale – Rodrigo E. Principe Feb 28 at 10:27
  • Ah, so it's just a pyramid. So that means that if I set it to 0, it will process the data in its native resolution, right? – IskJon Feb 28 at 12:33
  • @RodrigoE.Principe and Kuik these are both very elaborate answers and I appreciate you taking the time to do this! I have developed an inefficient script that uses arrays to solve the problem, but I will be sure to try both solutions once I am sure my script works and does everything I want it to. This will be the next step in writing a more elegant script... – IskJon Mar 4 at 8:04
1

Maybe you are interested in these kind of graphs, with precipitation per DOY and per year?

print(ui.Chart.image.doySeriesByYear(chirpsColl, 'precipitation', polygon, ee.Reducer.mean(), 1, ee.Reducer.mean()));

You can get the values as you have in the chart you present in your answer as:

// map over the image collection and set Doy and mean precipitation
var mapped = chirpsColl.map(function(image){
  // get the DOY
  var DOY = ee.Date(image.get('system:time_start')).format('D');
  // parse the Date output to a number
  DOY = ee.Number.parse(DOY).toInt();
  var value = image.reduceRegion(ee.Reducer.mean(), polygon, 1);
  return image.set('precMean', value.get('precipitation')).set('DOY', DOY); 
});

// put the values in a array. Use mean values for images with same DOY
var doys = ee.List.sequence(1,365);
var output = doys.map(function(i){
  //i = ee.Number(i).toInt();
  var valuesPerDOY = ee.List(mapped.filter(ee.Filter.eq('DOY', i)).aggregate_array('precMean'));
  var meanPrec = valuesPerDOY.reduce(ee.Reducer.mean());
  return meanPrec;
});
print(output);

Or, if you want a dictionary output with the values of each year plus the mean value over those years, use:

// put the values in a array. Use mean values for images with same DOY
var numberOfYears = ee.Number.parse(ee.Date(chirpsColl.first().get('system:time_start')).format('yyyy')).toInt()
                      .subtract(ee.Number.parse(ee.Date(chirpsColl.sort('system:time_start', false).first().get('system:time_start')).format('yyyy')).toInt()).abs().add(1);

var doys = ee.List.sequence(1,365);
var output = doys.map(function(i){
  var valuesPerDOY = ee.List(mapped.filter(ee.Filter.eq('DOY', i)).aggregate_array('precMean'));
  // some years have 1 less day. Append zero to those lists to have similar lengths
  valuesPerDOY = ee.List(ee.Algorithms.If(valuesPerDOY.length().eq(3), valuesPerDOY, valuesPerDOY.add(0)));
  var meanPrec = ee.Number(ee.Algorithms.If(valuesPerDOY.reduce(ee.Reducer.mean()), valuesPerDOY.reduce(ee.Reducer.mean()), 0));
  return ee.Dictionary.fromLists(['1981', '1982', '1983', 'mean'], valuesPerDOY.add(meanPrec));
});
print('output as dictionary with years + mean',output);

Link script

  • I have tried the former script and it works very well for the area I defined. However, I would now like to look at a much bigger area where the number of pixels exceeds the 10000000 allowed by GEE. Do you know if there is a way around that? – IskJon Mar 11 at 15:55
  • change the line for value to: var value = image.reduceRegion({reducer: ee.Reducer.mean(), geometry: polygon, scale: 1, maxPixels: 10e10}); It will set the maximum allowed pixels to a higher number in the reduceRegion call. Moreover, increase the scale to something like 5500, which I think approaches the native scale of 0.05 arc degrees (but search for that to make sure). – Kuik Mar 11 at 18:10
1

Here is an approach. Take in count that the array first index is 0 and corresponds to doy 1 (first day of year)

var doySeriesArray = function(imageCollection, region, scale,
                              regionReducer, yearReducer, 
                              startDay, endDay) {
  startDay = startDay || 1
  endDay = endDay || 366
  regionReducer = regionReducer || 'mean'
  yearReducer = yearReducer || 'mean'

  // Add doy to each image in the collection
  var addDoy = function(img) {
    img = ee.Image(img)
    var doy = img.date().getRelative('day', 'year')
    doy = ee.Number(doy).add(1) // somehow gets the first day of the year as 0 and so on..
    return img.set('doy', doy)
  }
  var withDoy = imageCollection.map(addDoy)

  // Reduce over doy
  var doys = ee.List.sequence(startDay, endDay)
  var reduceDoy = function(doy) {
    var filterDoy = withDoy.filterMetadata('doy', 'equals', doy)
    return ee.Image(filterDoy.reduce(yearReducer)).set('doy', doy)
  }
  var reducedDoy = doys.map(reduceDoy)

  // Reduce over region
  var reduceRegion = function(img) {
    img = ee.Image(img)
    var doy = img.get('doy')
    var reduction = img.reduceRegion({
      reducer: regionReducer,
      geometry: region,
      scale: scale
    })
    reduction = ee.Dictionary(reduction)
    return ee.Algorithms.If(reduction.contains('precipitation_mean'),
                            reduction.get('precipitation_mean'),
                            0)
  }

  return reducedDoy.map(reduceRegion)
}

var array = doySeriesArray(chirpsColl, polygon, 1)
print(array)

link: https://code.earthengine.google.com/1da18e2a0341ebc14feec723a683e3c1

I have downloaded the CSV from the chart, and as far as I could see the results are the same.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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