Google Earth Engine Map.addLayer – Fixing Issue with Adding Bands

evigoogle-earth-enginegoogle-earth-engine-javascript-apisentinel-2

I'm working on calculating the Enhanced Vegetation Index (EVI) of a Sentinel-2 image in Google Earth Engine. My code is:

//evi visual parameters
var evivisparam = {bands: ['B4', 'B8', 'B2'], min: -11000, max: 11000};


//evi calculation of img161
var evi = img161.expression(
    '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
      'NIR': img161.select('B8'),
      'RED': img161.select('B4'),
      'BLUE': img161.select('B2')
});
Map.addLayer(evi, evivisparam, 'EVI img161');

When I run this, the console prints the error:

EVI img161: Layer error: Image.visualize: No band named 'B4'. Available band names: [constant].

I know that these bands do exist from using

var bandnamesimg161 = img161.bandNames();
print(bandnamesimg161);

which listed the 16 Sentinel-2 bands, including the 3 mentioned. Why does Google Earth Engine not recognize the bands, and how do I make it print the image 'evi'?

Best Answer

(Note: I know nothing about appropriate visualization of "EVI" data; my suggestions in this answer are general advice on Earth Engine programming and not specifically recommended as good visualizations.)

I know that these bands do exist…

You checked img161, where those band names do exist, but you're trying to visualize evi, which does not have those bands — it has one band, which you just computed using an expression:

var evi = img161.expression(
    '2.5 * ((NIR - RED) / (NIR + 6 * RED - 7.5 * BLUE + 1))', {
      'NIR': img161.select('B8'),
      'RED': img161.select('B4'),
      'BLUE': img161.select('B2')
});

When you compute an image by doing arithmetic on single band images (as you have provided here using .select()), the output is also single-band (and the band name is often irrelevant — here it is 'constant' because the very first input is the constant-image-value 2.5).

You have one band, but your evivisparam specifies three bands. The question, then, is: what kind of visualization do you want?

  • If grayscale will do, remove bands from the visualization parameters.

    var evivisparam = {min: -1, max: 1};
    

    Grayscale

  • If you want a color gradient, specify a palette in the visualization parameters.

    var evivisparam = {min: -1, max: 1, palette: ['FF0000', '000000', '00FF44']};
    

    enter image description here

  • If you want one color channel to be the EVI value and others to be the original bands, then you need to recombine the computed EVI band with the original image bands, and specify suitable visualization parameters for red, green, and blue:

    var evivisparam = {
      min: [-11000, -1, -11000],
      max: [11000, 1, 11000],
      bands: ['B4', 'evi', 'B2']
    
    };
    var img161WithEvi = img161.addBands(evi.rename('evi'));
    Map.addLayer(img161WithEvi, evivisparam, 'EVI img161');
    

    3 bands

Related Question