1

I want to create a correlation chart between LST and NDVI (with trendlines and R2 value inside the chart)for an area in Google Earth Engine (GEE). I tried many solutions (adding both images to image collection, merging them). But nothing seems to work.

I am a newbie to GEE.

The code is as follows

//Landsat 5 Images as L5
// Study Region as roi
var image = L5.filterBounds(roi)
            .filterDate('2005-01-01','2005-12-31')
            .filterMetadata('CLOUD_COVER','less_than',0.1)
            .mean()
            .clip(roi)

// LST Calculation
var radiance = image.expression(    //Radiance
  '((15.303-1.238)/(255-1)*(B6-1)+1.238)', {
    B6: image.select('B6')
  }
)
var LST = image.expression(         //At Sensor Brightness
  '(K2 / (2.303 * (log10(K1 / L)))+ 1) -273.15', {
    K1: 607.76,       //Calibration Constant 1
    K2: 1260.56,     //Calibration Constant 2
    L: radiance
  }
)
// Add LST to Map
Map.addLayer(LST, {min: 10, max: 40, palette: ['green','blue', 'orange','red']}, 'LST')


// Mean LST
var meanLST = LST.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry: roi.geometry(),
  scale: 30,
});
print('Mean LST:', meanLST)


// NDVI Calculation
var ndvi = image.normalizedDifference(['B4', 'B3'])

//Add NDVI to Map
Map.addLayer(ndvi, {min: -1, max: 1, palette: ['red','orange','yellow','green']}, 'NDVI')

// Mean NDVI
var meanndvi = ndvi.reduceRegion({
  reducer: ee.Reducer.mean(),
  geometry: roi.geometry(),
  scale: 30,
});
print('Mean NDVI:', meanndvi)

// Need to Create Correlation Plot (LST vs NDVI) with trendlines and R2 values inside the chart
1
  • Here says, R squared value can not be shown in the graph. For correlation chart, you can checkout this question.
    – Padmanabha
    Jul 22, 2021 at 13:00

1 Answer 1

1

This could be one approach: First do the linear regression with reduceRegion(), to get the coefficients of your trend line and R2. Combine your NDVI and LST into a single image and sample it. Map over the samples and create four features for each. One with the observation, one with the model value, one with the model value + n x R2 and finally one with the model value - n x R2. Assign a series property for each of these. Finally, do a scatter plot of these, grouping into series by the series property.

https://code.earthengine.google.com/21222a0301a435acfa49702e102aa305

var reduced = ee.Image(1).rename('constant')
  .addBands(ndvi)
  .addBands(LST)
  .float()
  .reduceRegion({
    reducer: ee.Reducer.linearRegression(2, 1),
    geometry: roi,
    scale: 30,
    bestEffort: true,
    maxPixels: 10
  })
var coefficients = ee.Array(reduced.get('coefficients'))
var offset = coefficients.get([0, 0])
var slope = coefficients.get([1, 0])
var r2 = ee.Array(reduced.get('residuals')).get([0])
var errors = 3 // How many r2 away to highlight

var samples = ndvi
  .addBands(LST)
  .select(['ndvi', 'lst'])
  .sample({
    region: roi,
    scale: 30,
    numPixels: 500,
    geometries: true
  })
  .map(function (sample) {
    var ndvi = sample.getNumber('ndvi')
    var model = ndvi.multiply(slope).add(offset)
    var upper = model.add(r2.multiply(errors))
    var lower = model.subtract(r2.multiply(errors))
    return ee.FeatureCollection([
      sample.set('series', 'observations'),
      ee.Feature(sample.geometry(), {
        ndvi: ndvi,
        lst: upper,
        series: 'upper'
      }),
      ee.Feature(sample.geometry(), {
        ndvi: ndvi,
        lst: model,
        series: 'model'
      }),
      ee.Feature(sample.geometry(), {
        ndvi: ndvi,
        lst: lower,
        series: 'lower'
      })
    ])
  })
  .flatten()

var chart = ui.Chart.feature
  .groups({
    features: samples, 
    xProperty: 'ndvi', 
    yProperty: 'lst', 
    seriesProperty: 'series'
  })
  .setChartType('ScatterChart')
  .setOptions({
    // Order of seeries seems to be the order they are encountered
    // So controlled when creating the FeatureCollection
    series: {
      0: {pointSize: 1, color: 'blue'}, // observations
      1: {lineWidth: 1, color: 'lightgray', pointSize: 0}, // upper
      2: {lineWidth: 1, color: 'red', pointSize: 0}, // model
      3: {lineWidth: 1, color: 'lightgray', pointSize: 0} // lower
    },
    
  })

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.