Image Visualization

The Get Started page illustrates how to visualize an image using Map.addLayer(). If you add a layer to the map without any additional parameters, by default the Code Editor assigns the first three bands to red, green and blue, respectively. The default stretch is based on the type of data in the band (e.g. floats are stretched in [0,1], 16-bit data are stretched to the full range of possible values), which may or may not be suitable. To achieve desirable visualization effects, you can provide visualization parameters to Map.addLayer(). Specifically, the parameters are:

Visualization parameters for Map.addLayer()
Parameter Description Type
bands Comma-delimited list of three band names to be mapped to RGB list
min Value(s) to map to 0 number or list of three numbers, one for each band
max Value(s) to map to 255 number or list of three numbers, one for each band
gain Value(s) by which to multiply each pixel value number or list of three numbers, one for each band
bias Value(s) to add to each DN number or list of three numbers, one for each band
gamma Gamma correction factor(s) number or list of three numbers, one for each band
palette List of CSS-style color strings (single-band images only) comma-separated list of hex strings
opacity The opacity of the layer (0.0 is fully transparent and 1.0 is fully opaque) number
format Either "jpg" or "png" string

RGB composites

The following illustrates the use of parameters to style a Landsat 8 image as a false-color composite:

// Load an image.
var image = ee.Image('LANDSAT/LC08/C01/T1_TOA/LC08_044034_20140318');

// Define the visualization parameters.
var vizParams = {
  bands: ['B5', 'B4', 'B3'],
  min: 0,
  max: 0.5,
  gamma: [0.95, 1.1, 1]

// Center the map and display the image.
Map.setCenter(-122.1899, 37.5010, 10); // San Francisco Bay
Map.addLayer(image, vizParams, 'false color composite');

In this example, band ‘B5’ is assigned to red, ‘B4’ is assigned to green, and ‘B3’ is assigned to blue. The result should look something like Figure 1.

Figure 1. Landsat 8 false color composite of San Francisco bay area, California, USA.

Color palettes

To display a single band of an image in color, set the palette parameter with a color ramp represented by a list of CSS-style color strings. (See this reference for more information). The following example illustrates how to use colors from cyan (‘00FFFF’) to blue (‘0000FF’) to render a Normalized Difference Water Index (NDWI) image:

// Load an image.
var image = ee.Image('LANDSAT/LC08/C01/T1_TOA/LC08_044034_20140318');

// Create an NDWI image, define visualization parameters and display.
var ndwi = image.normalizedDifference(['B3', 'B5']);
var ndwiViz = {min: 0.5, max: 1, palette: ['00FFFF', '0000FF']};
Map.addLayer(ndwi, ndwiViz, 'NDWI', false);

In this example, note that the min and max parameters indicate the range of pixel values to which the palette should be applied. Intermediate values are linearly stretched. Also note that the opt_show parameter is set to false. This results in the visibility of the layer being off when it is added to the map. It can always be turned on again using the Layer Manager in the upper right corner of the map. The result should look something like Figure 2.

Figure 2. Landsat 8 NDWI, San Francisco bay area, USA. Same area as Figure 1. Cyan are low values, blue are high values.


You can use image.updateMask() to set the opacity of individual pixels based on where pixels in a mask image are non-zero. Pixels equal to zero in the mask are excluded from computations and the opacity is set to 0 for display. The following example uses an NDWI threshold (see the Relational Operations section for information on thresholds) to update the mask on the NDWI layer created previously:

// Mask the non-watery parts of the image, where NDWI < 0.4.
var ndwiMasked = ndwi.updateMask(ndwi.gte(0.4));
Map.addLayer(ndwiMasked, ndwiViz, 'NDWI masked');

Visualization images

Use the image.visualize() method to convert an image into an 8-bit RGB image for display or export. For example, to convert the false-color composite and NDWI to 3-band display images, use:

// Create visualization layers.
var imageRGB = image.visualize({bands: ['B5', 'B4', 'B3'], max: 0.5});
var ndwiRGB = ndwiMasked.visualize({
  min: 0.5,
  max: 1,
  palette: ['00FFFF', '0000FF']


You can use masking and imageCollection.mosaic() (see the Mosaicking section for information on mosaicking) to achieve various cartographic effects. The mosaic() method renders layers in the output image according to their order in the input collection. The following example uses mosaic() to combine the masked NDWI and the false color composite and obtain a new visualization:

// Mosaic the visualization layers and display (or export).
var mosaic = ee.ImageCollection([imageRGB, ndwiRGB]).mosaic();
Map.addLayer(mosaic, {}, 'mosaic');

In this example, observe that a list of the two visualization images is provided to the ImageCollection constructor. The order of the list determines the order in which the images are rendered on the map. The result should look something like Figure 3.

Figure 3. Mosaic of a Landsat 8 false color composite and NDWI. San Francisco bay area, USA.


The image.clip() method is useful for achieving cartographic effects. The following example clips the mosaic shown in Figure 3 to an arbitrary buffer zone around the city of San Francisco:

// Create a circle by drawing a 20000 meter buffer around a point.
var roi = ee.Geometry.Point([-122.4481, 37.7599]).buffer(20000);

// Display a clipped version of the mosaic.

In the previous example, note that the coordinates are provided to the Geometry constructor and the buffer length is specified as 20,000 meters. Learn more about geometries on the Geometries page. The result, shown with the map in the background, should look something like Figure 4.

Figure 4. The mosaic shown in Figure 4, clipped to a buffer around San Francisco, California, USA.

Rendering categorical maps

Palettes are also useful for rendering discrete valued maps, for example a land cover map. In the case of multiple classes, use the palette to supply a different color for each class. (The image.remap() method may be useful in this context, to convert arbitrary labels to consecutive integers). The following example uses a palette to render land cover categories:

// Load 2012 MODIS land cover and select the IGBP classification.
var cover = ee.Image('MODIS/051/MCD12Q1/2012_01_01')

// Define a palette for the 18 distinct land cover classes.
var igbpPalette = [
  'aec3d4', // water
  '152106', '225129', '369b47', '30eb5b', '387242', // forest
  '6a2325', 'c3aa69', 'b76031', 'd9903d', '91af40',  // shrub, grass
  '111149', // wetlands
  'cdb33b', // croplands
  'cc0013', // urban
  '33280d', // crop mosaic
  'd7cdcc', // snow and ice
  'f7e084', // barren
  '6f6f6f'  // tundra

// Specify the min and max labels and the color palette matching the labels.
Map.setCenter(-99.229, 40.413, 5);
             {min: 0, max: 17, palette: igbpPalette},
             'IGBP classification');

The result of the previous example should look something like Figure 5.

Figure 5. MODIS 2012 land cover using the IGBP classification.

Styled Layer Descriptors

You can use a Styled Layer Descriptor (SLD) to render imagery for display. Provide image.sldStyle() with an XML description of the symbolization and coloring of the image, specifically the RasterSymbolizer element. Learn more about the RasterSymbolizer element here. For example, to render the land cover map described in the Rendering categorical maps section with an SLD, use:

var cover = ee.Image('MODIS/051/MCD12Q1/2012_01_01').select('Land_Cover_Type_1');

// Define an SLD style of discrete intervals to apply to the image.
var sld_intervals =
'<RasterSymbolizer>' +
  '<ColorMap type="intervals" extended="false">' +
    '<ColorMapEntry color="#aec3d4" quantity="0" label="Water"/>' +
    '<ColorMapEntry color="#152106" quantity="1" label="Evergreen Needleleaf Forest"/>' +
    '<ColorMapEntry color="#225129" quantity="2" label="Evergreen Broadleaf Forest"/>' +
    '<ColorMapEntry color="#369b47" quantity="3" label="Deciduous Needleleaf Forest"/>' +
    '<ColorMapEntry color="#30eb5b" quantity="4" label="Deciduous Broadleaf Forest"/>' +
    '<ColorMapEntry color="#387242" quantity="5" label="Mixed Deciduous Forest"/>' +
    '<ColorMapEntry color="#6a2325" quantity="6" label="Closed Shrubland"/>' +
    '<ColorMapEntry color="#c3aa69" quantity="7" label="Open Shrubland"/>' +
    '<ColorMapEntry color="#b76031" quantity="8" label="Woody Savanna"/>' +
    '<ColorMapEntry color="#d9903d" quantity="9" label="Savanna"/>' +
    '<ColorMapEntry color="#91af40" quantity="10" label="Grassland"/>' +
    '<ColorMapEntry color="#111149" quantity="11" label="Permanent Wetland"/>' +
    '<ColorMapEntry color="#cdb33b" quantity="12" label="Cropland"/>' +
    '<ColorMapEntry color="#cc0013" quantity="13" label="Urban"/>' +
    '<ColorMapEntry color="#33280d" quantity="14" label="Crop, Natural Veg. Mosaic"/>' +
    '<ColorMapEntry color="#d7cdcc" quantity="15" label="Permanent Snow, Ice"/>' +
    '<ColorMapEntry color="#f7e084" quantity="16" label="Barren, Desert"/>' +
    '<ColorMapEntry color="#6f6f6f" quantity="17" label="Tundra"/>' +
  '</ColorMap>' +
Map.addLayer(cover.sldStyle(sld_intervals), {}, 'IGBP classification styled');

To create a visualization image with a color ramp, set the type of the ColorMap to ‘ramp’. The following example compares the ‘interval’ and ‘ramp’ types for rendering a DEM:

// Load SRTM Digital Elevation Model data.
var image = ee.Image('CGIAR/SRTM90_V4');

// Define an SLD style of discrete intervals to apply to the image.
var sld_intervals =
  '<RasterSymbolizer>' +
    '<ColorMap type="intervals" extended="false" >' +
      '<ColorMapEntry color="#0000ff" quantity="0" label="0"/>' +
      '<ColorMapEntry color="#00ff00" quantity="100" label="1-100" />' +
      '<ColorMapEntry color="#007f30" quantity="200" label="110-200" />' +
      '<ColorMapEntry color="#30b855" quantity="300" label="210-300" />' +
      '<ColorMapEntry color="#ff0000" quantity="400" label="310-400" />' +
      '<ColorMapEntry color="#ffff00" quantity="1000" label="410-1000" />' +
    '</ColorMap>' +

// Define an sld style color ramp to apply to the image.
var sld_ramp =
  '<RasterSymbolizer>' +
    '<ColorMap type="ramp" extended="false" >' +
      '<ColorMapEntry color="#0000ff" quantity="0" label="0"/>' +
      '<ColorMapEntry color="#00ff00" quantity="100" label="100" />' +
      '<ColorMapEntry color="#007f30" quantity="200" label="200" />' +
      '<ColorMapEntry color="#30b855" quantity="300" label="300" />' +
      '<ColorMapEntry color="#ff0000" quantity="400" label="400" />' +
      '<ColorMapEntry color="#ffff00" quantity="500" label="500" />' +
    '</ColorMap>' +

// Add the image to the map using both the color ramp and interval schemes.
Map.setCenter(-76.8054, 42.0289, 8);
Map.addLayer(image.sldStyle(sld_intervals), {}, 'SLD intervals');
Map.addLayer(image.sldStyle(sld_ramp), {}, 'SLD ramp');

SLDs are also useful for stretching pixel values to improve visualizations of continuous data. For example, the following code compares the results of an arbitrary linear stretch with a min-max ‘Normalization’ and a ‘Histogram’ equalization:

// Load a Landsat 8 raw image.
var image = ee.Image('LANDSAT/LC08/C01/T1/LC08_044034_20140318');

// Define a RasterSymbolizer element with '_enhance_' for a placeholder.
var template_sld =
  '<RasterSymbolizer>' +
    '<ContrastEnhancement><_enhance_/></ContrastEnhancement>' +
    '<ChannelSelection>' +
      '<RedChannel>' +
        '<SourceChannelName>B5</SourceChannelName>' +
      '</RedChannel>' +
      '<GreenChannel>' +
        '<SourceChannelName>B4</SourceChannelName>' +
      '</GreenChannel>' +
      '<BlueChannel>' +
        '<SourceChannelName>B3</SourceChannelName>' +
      '</BlueChannel>' +
    '</ChannelSelection>' +

// Get SLDs with different enhancements.
var equalize_sld = template_sld.replace('_enhance_', 'Histogram');
var normalize_sld = template_sld.replace('_enhance_', 'Normalize');

// Display the results.
Map.centerObject(image, 10);
Map.addLayer(image, {bands: ['B5', 'B4', 'B3'], min: 0, max: 15000}, 'Linear');
Map.addLayer(image.sldStyle(equalize_sld), {}, 'Equalized');
Map.addLayer(image.sldStyle(normalize_sld), {}, 'Normalized');

Points of note in reference to using SLDs in Earth Engine:

  • OGC SLD 1.0 and OGC SE 1.1 are supported.
  • The XML document passed in can be complete, or just the RasterSymbolizer element and down.
  • Bands may be selected by their Earth Engine names or index ('1', '2', ...).
  • The Histogram and Normalize contrast stretch mechanisms are not supported for floating point imagery.
  • Opacity is only taken into account when it is 0.0 (transparent). Non-zero opacity values are treated as completely opaque.
  • The OverlapBehavior definition is currently ignored.
  • The ShadedRelief mechanism is not currently supported.
  • The ImageOutline mechanism is not currently supported.
  • The Geometry element is ignored.
  • The output image will have histogram_bandname metadata if histogram equalization or normalization is requested.

Thumbnail images

Use the ee.Image.getThumbURL() method to generate a PNG or JPEG thumbnail image for an ee.Image object. Printing the outcome of an expression ending with a call to getThumbURL() results in a URL being printed to the console. Visiting the URL sets Earth Engine servers to work on generating the requested thumbnail on-the-fly. The image is displayed in the browser when processing completes. It can be downloaded by selecting appropriate options from the image’s right-click context menu.

Figure 6. SRTM digital elevation model displayed as a PNG thumbnail in the browser.

The getThumbURL() method shares parameters with Map.addLayer(), described in the visualization parameters table above. Additionally, it takes optional dimensions, region, and crs arguments that control the spatial extent, size, and display projection of the thumbnail.

Additional parameters for ee.Image.getThumbURL() with note on format
Parameter Description Type
dimensions Thumbnail dimensions in pixel units. If a single integer is provided, it defines the size of the image's larger aspect dimension and scales the smaller dimension proportionally. Defaults to 512 pixels for the larger image aspect dimension. A single integer or string in the format: 'WIDTHxHEIGHT'
region The geospatial region of the image to render. The whole image by default, or the bounds of a provided geometry. GeoJSON or a 2-D list of at least three point coordinates that define a linear ring
crs The target projection e.g. 'EPSG:3857'. Defaults to WGS84 ('EPSG:4326'). String
format Defines thumbnail format as either PNG or JPEG. The default PNG format is implemented as RGBA, where the alpha channel represents valid and invalid pixels, defined by the image’s mask(). Invalid pixels are transparent. The optional JPEG format is implemented as RGB, where invalid image pixels are zero filled across RGB channels. String; either 'png' or 'jpg'

A single-band image will default to grayscale unless a palette argument is supplied. A multi-band image will default to RGB visualization of the first three bands, unless a bands argument is supplied. If only two bands are provided, the first band will map to red, the second to blue, and the green channel will be zero filled.

The following are a series of examples demonstrating various combinations of getThumbURL() parameter arguments. Visit the URLs printed to the console when you run this script to view the thumbnails.

// Fetch a digital elevation model.
var image = ee.Image('CGIAR/SRTM90_V4');

// Request a default thumbnail of the DEM with defined linear stretch.
// Set masked pixels (ocean) to 1000 so they map as gray.
var thumbnail1 = image.unmask(1000).getThumbURL({
  'min': 0,
  'max': 3000,
  'dimensions': 500,
print('Default extent:', thumbnail1);

// Specify region by rectangle, define palette, set larger aspect dimension size.
var thumbnail2 = image.getThumbURL({
  'min': 0,
  'max': 3000,
  'palette': ['00A600','63C600','E6E600','E9BD3A','ECB176','EFC2B3','F2F2F2'],
  'dimensions': 500,
  'region': ee.Geometry.Rectangle([-84.6, -55.9, -32.9, 15.7]),
print('Rectangle region and palette:', thumbnail2);

// Specify region by a linear ring and set display CRS as Web Mercator.
var thumbnail3 = image.getThumbURL({
  'min': 0,
  'max': 3000,
  'palette': ['00A600','63C600','E6E600','E9BD3A','ECB176','EFC2B3','F2F2F2'],
  'region': ee.Geometry.LinearRing([[-84.6, 15.7], [-84.6, -55.9], [-32.9, -55.9]]),
  'dimensions': 500,
  'crs': 'EPSG:3857'
print('Linear ring region and specified crs', thumbnail3);