1

I am currently trying to plot, in the same chart, a time-series for monthly and yearly soil moisture. I have an ImageCollection which has 480 images (one per month), and another ImageCollection that has 40 images (one per year).

I am able to plot them separately but I have not found a way to stack both plots in a single chart. Some options I looked up were (a) to do an innerJoin() beforehand, but this downsamples the monthly collection down from 480 to 40 images, or (b) to fill gaps in the yearly collection with Na (similar to fillNa with pandas), but I could not figure out a way to do so.

Here is the code sample:

// --- GLOBALS ---

var dateStart = ee.Date('1980-01-01'); 
var dateEnd = ee.Date('2019-12-31');
var scale = 1000;
var studyArea = ee.FeatureCollection('TIGER/2018/States').filterMetadata('NAME', 'equals', 'Nevada');

var monthlySoil = ee.ImageCollection('IDAHO_EPSCOR/TERRACLIMATE') // Load data
                .filter(ee.Filter.date(dateStart, dateEnd))
                .select('soil');

// --- TIME SERIES ---

// Create list of dates for time series
var dateListYearly = ee.List.sequence(0,dateEnd.difference(dateStart,'year').round(),1);
var makeDateListYearly = function(n) {return dateStart.advance(n,'year')};
dateListYearly = dateListYearly.map(makeDateListYearly);

// Yearly data
var yearlySoil = [];
yearlySoil = dateListYearly.map(function(d){ // Resample yearly
  var start = ee.Date(d);
  var end = ee.Date(d).advance(1,'year');
  var dateRange = ee.DateRange(start,end);
  var yearlySoilInter = monthlySoil
                      .filterDate(dateRange)
                      .mean()
                      .clip(studyArea)
                      .rename('Yearly');
  return(yearlySoilInter.set('system:time_start', start.millis())); // Add time band
});
yearlySoil = ee.ImageCollection(yearlySoil);

// --- PLOT ---

var options1 = { // Monthly 
  title: 'SM Monthly',
  fontSize: 12,
  hAxis: {title: 'Date'},
  vAxis: {title: 'SM (mm)'},
  series: {0: {color: 'red'}}
};
print(ui.Chart.image.series(monthlySoil, studyArea, ee.Reducer.mean(), scale).setOptions(options1));

var options2 = { // Yearly 
  title: 'SM yearly',
  fontSize: 12,
  hAxis: {title: 'Date'},
  vAxis: {title: 'SM (mm)'},
  series: {0: {color: 'blue'}}
};
print(ui.Chart.image.series(yearlySoil, studyArea, ee.Reducer.mean(), scale).setOptions(options2));

And link: https://code.earthengine.google.com/1443f7796cd2d1527e4ca9fec145f4b7

Ryan M
  • 18,333
  • 31
  • 67
  • 74
MadeleineN
  • 148
  • 6

1 Answers1

2

Similar to your idea of filling the gaps with NAs, I added an empty band to each collection to match the corresponding band in the other collection. Then I merged the collections and made a chart.

s2sr = s2sr.filterBounds(roi).filter(ee.Filter.calendarRange(2020, 2020, 'year'))
l8sr = l8sr.filterBounds(roi).filter(ee.Filter.calendarRange(2020, 2020, 'year'))

// compute some bands to add to each collection
var addS2Bands = function(image){
  var s2nd = image.normalizedDifference(['B4','B3']).rename('s2_nd')
  var l8nd = ee.Image().rename('l8_nd') // must add an empty band for select() to work on all images
  return image.addBands(s2nd).addBands(l8nd)
}
var addL8Bands = function(image){
  var l8nd = image.normalizedDifference(['B4','B3']).rename('l8_nd')
  var s2nd = ee.Image().rename('s2_nd')
  return image.addBands(l8nd).addBands(s2nd)
}
l8sr = l8sr.map(addL8Bands)
s2sr = s2sr.map(addS2Bands)


// merge the collections
var merged = l8sr.merge(s2sr).select(['l8_nd', 's2_nd'])

// plot the collection
var chart = ui.Chart.image.series({
  imageCollection: merged,
  region: roi,
  reducer: ee.Reducer.mean(),
  scale: 30
})
print(chart)

https://code.earthengine.google.com/?scriptPath=users%2Fcaseyengstrom%2Freprex%3AuiChartMultiCollection

cengstro
  • 260
  • 1
  • 9