2

I'm trying to calculate and plot correlation coefficients between two Image Collections, which are monthly NDVI and MODIS hotspot counts (where hotspot counts represents the number of times a pixel has been detected as a hotspot, per month.) Each is a stack of aggregated monthly images with the same projection and scale. I want to get correlation values for each image pair in the stack (monthly correlation values), and plot them in a series. However, my MODIS hotspots data has masked pixels (where there are no hotspots), and NDVI does not. This means some of the MODIS pixels have a band value of 'Masked', which cannot pair with an NDVI value to get correlation.

I think this is why I get the error: "Error generating chart: Data column(s) for axis #0 cannot be of type string" when I try to generate this chart. How can I get Pearson's Correlation for only unmasked MODIS values and their matching NDVI pixels? In other words, I want to run a correlation between MODIS counts and NDVI for each month, but ONLY where MODIS is unmasked. Alternately, I could find the correlation between the sum of all unmasked hotspot counts and the mean NDVI for the study area, for all months (rather than pixel-wise), but I'm not sure how I would do this.

Here is the link to the full code: https://code.earthengine.google.com/38726b77beeb9924655e87949a57034f

Here is the relevant code snippet:

// Add bands: zip the image collections together into one collection. var size = hotspots_monthly.size(); var merged = hotspots_monthly.toList(size).zip(ndvi.toList(size)) .map(function(row) { return ee.Image(ee.List(row).get(0)) .addBands(ee.List(row).get(1)) }); var mergedIC = ee.ImageCollection(merged); print('zipped collection', mergedIC); // Make a band correlation chart. print(ui.Chart.image.series({ imageCollection: mergedIC.select(['MaxFRP','NDVI']), region: geometry, reducer: ee.Reducer.pearsonsCorrelation(), scale: 1000, //xProperty: 'system:time_start' })); 

1 Answer 1

3

It seems like the charting library doesn't like NaN values. To workaround this, you can manually calculate the correlations in an ee.FeatureCollection, filter out NaN, then create the chart with ui.Chart.feature.byFeature().

It's MODIS giving you problems with masked out pixels. Since you only want a count of the number of fires, you could do count.unmask(0), assuming there are no fires for masked out pixels. That way, you get more data for your correlations.

You can also optimize your code a bit. Avoid clip() and reproject() when you don't need them. It's also a good idea to keep data in collections instead of using lists. You could, for instance, create your monthly count and NDVI at the same time. That way, you don't have to turn your image collections into lists and zip them.

Altogether, it could look something like this:

var terra = ee.ImageCollection("MODIS/061/MOD14A1").select('MaxFRP') .filterBounds(geometry) var aqua = ee.ImageCollection("MODIS/061/MYD14A1").select('MaxFRP') .filterBounds(geometry) var ndvi = ee.ImageCollection("MODIS/061/MOD13A3") .filterBounds(geometry) var years = ee.List.sequence(start_year, end_year) var months = ee.List.sequence(start_month, end_month) var byMonth = ee.ImageCollection(years .map(function (year) { return months.map(function (month) { return fireCountAndNdvi(year, month) }) }) .flatten() ) var correlation = byMonth .map(pearsonsCorrelation) .filter(ee.Filter.lte('correlation', 1)) // Hack to get rid of NaN print(ui.Chart.feature.byFeature({ features: correlation, xProperty: 'date', yProperties: 'correlation' })) function fireCountAndNdvi(year, month) { var date = ee.Date.fromYMD(year, month, 1) var terraCount = terra .filterDate(date.getRange('month')) .count() .unmask(0) var aquaCount = aqua .filterDate(date.getRange('month')) .count() .unmask(0) var ndviForMonth = ndvi .select('NDVI') .filterDate(date.getRange('month')) .median() var count = terraCount.add(aquaCount).rename('count') var image = ndviForMonth.addBands(count) return image .updateMask(image.mask().reduce(ee.Reducer.min())) .set('system:time_start', date.millis()) } function pearsonsCorrelation(image) { var reduced = image.reduceRegion({ reducer: ee.Reducer.pearsonsCorrelation(), geometry: geometry, scale: 1000, crs: 'EPSG:4326', tileScale: 16 }) return ee.Feature(null, reduced) .set('date', image.date()) } 

https://code.earthengine.google.com/2fe5d42a6bb85e7dc731831caa15d453

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.