Map Image#

The geetools extension contains a set of functions for rendering maps from ee.Image objects. Use the following function descriptions and examples to determine the best function and chart type for your purpose.

github colab

Set up environment#

Install the required packages and authenticate your Earth Engine account.

# uncomment if installation of libs is necessary
# !pip install earthengine-api geetools
from IPython.display import display
from matplotlib import pyplot as plt

import ee
import geetools #noqa: F401
# uncomment if authetication to GEE is needed
# ee.Authenticate()
# ee.Intialize(project="<your_project>")

Example data#

The following examples rely on the “COPERNICUS/S2_HARMONIZED” ee.ImageCollection filtered between 2022-06-01 and 2022-06-30. We then build the NDVI spectral indice and use mosaic to get an ee.Image object. This object is clipped over the Vatican city as it’s one of the smallest country in the world.

# load the vatican
level0 = ee.FeatureCollection("FAO/GAUL/2015/level0")
vatican = level0.filter(ee.Filter.eq("ADM0_NAME", "Holy See"))

# pre-process the imagecollection and mosaic the month of June 2022
image = (
    ee.ImageCollection('COPERNICUS/S2_HARMONIZED')
    .filterDate('2022-06-01', '2022-06-30')
    .filterBounds(vatican)
    .geetools.maskClouds()
    .geetools.spectralIndices("NDVI")
    .mosaic()
)

Map Raster#

See API

plot: geetools.ImageAccessor.plot not found

An ee.image is a raster representation of the Earth’s surface. The plot function allows you to visualize the raster data on a map. The function provides options to customize the visualization, such as the color palette, opacity, and the visualization range.

Map pseudo color#

A pseudo-color image is a single-band raster image that uses a color palette to represent the data. The following example demonstrates how to plot the NDVI pseudo-color image using the plot function.

First create a matplotlib figure and axis. Then you can add the map to the axis. Provide a single element list in the bands parameter to plot the NDVI image. As per interactive representation an image needs to be reduced to a region, here “Vatican City”. In this example we also select a pseudo-mercator projection and we displayed the ee.FeatureCollection on top of it. Now that we have the plot, we can customize it with matplotlib. For example, we can add a title and a colorbar. Now that we have the plot, we can customize it with matplotlib. For example, we can add a title and a colorbar.

fig, ax = plt.subplots()

image.geetools.plot(
    bands = ["NDVI"],
    ax=ax,
    region=vatican.geometry(),
    crs="EPSG:3857",
    scale=10,
    fc=vatican,
    cmap="viridis",
    color="k"
)

# as it's a figure you can then edit the information as you see fit
ax.set_title("NDVI in Vatican City")
ax.set_xlabel("x coordinates (m)")
ax.set_ylabel("y coordinates (m)")
fig.colorbar(ax.images[0], label="NDVI")

plt.show()
---------------------------------------------------------------------------
HttpError                                 Traceback (most recent call last)
File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/ee/data.py:359, in _execute_cloud_call(call, num_retries)
    358 try:
--> 359   return call.execute(num_retries=num_retries)
    360 except googleapiclient.errors.HttpError as e:

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/googleapiclient/_helpers.py:130, in positional.<locals>.positional_decorator.<locals>.positional_wrapper(*args, **kwargs)
    129         logger.warning(message)
--> 130 return wrapped(*args, **kwargs)

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/googleapiclient/http.py:938, in HttpRequest.execute(self, http, num_retries)
    937 if resp.status >= 300:
--> 938     raise HttpError(resp, content, uri=self.uri)
    939 return self.postproc(resp, content)

HttpError: <HttpError 400 when requesting https://earthengine.googleapis.com/v1/projects/ee-geetools/value:compute?prettyPrint=false&alt=json returned "ImageCollection.mosaic: Error in map(ID=20220604T100031_20220604T100034_T32TQM):
Image.select: Band pattern 'SCL' did not match any bands. Available bands: [B1, B2, B3, B4, B5, B6, B7, B8, B8A, B9, B10, B11, B12, QA10, QA20, QA60, MSK_CLASSI_OPAQUE, MSK_CLASSI_CIRRUS, MSK_CLASSI_SNOW_ICE, CLOUD_MASK]". Details: "ImageCollection.mosaic: Error in map(ID=20220604T100031_20220604T100034_T32TQM):
Image.select: Band pattern 'SCL' did not match any bands. Available bands: [B1, B2, B3, B4, B5, B6, B7, B8, B8A, B9, B10, B11, B12, QA10, QA20, QA60, MSK_CLASSI_OPAQUE, MSK_CLASSI_CIRRUS, MSK_CLASSI_SNOW_ICE, CLOUD_MASK]">

During handling of the above exception, another exception occurred:

EEException                               Traceback (most recent call last)
Cell In[6], line 3
      1 fig, ax = plt.subplots()
----> 3 image.geetools.plot(
      4     bands = ["NDVI"],
      5     ax=ax,
      6     region=vatican.geometry(),
      7     crs="EPSG:3857",
      8     scale=10,
      9     fc=vatican,
     10     cmap="viridis",
     11     color="k"
     12 )
     14 # as it's a figure you can then edit the information as you see fit
     15 ax.set_title("NDVI in Vatican City")

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/geetools/ee_image.py:1726, in ImageAccessor.plot(self, bands, region, ax, fc, cmap, crs, scale, color)
   1719 grid_params = helpers.fit_geometry(
   1720     geometry=sg.shape(region.bounds().getInfo()),
   1721     grid_crs=crs,
   1722     grid_scale=(scale, -scale),
   1723 )
   1725 # extract the image as a xarray dataset
-> 1726 ds = xarray.open_dataset(
   1727     ee.ImageCollection([self._obj]),
   1728     engine="ee",
   1729     request_byte_limit=REQUEST_BYTE_LIMIT,
   1730     **grid_params,
   1731 )
   1733 # extract all the bands as dataarrays objects
   1734 bands_da = [ds[b][0, :, :] for b in bands]

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/xarray/backends/api.py:687, in open_dataset(filename_or_obj, engine, chunks, cache, decode_cf, mask_and_scale, decode_times, decode_timedelta, use_cftime, concat_characters, decode_coords, drop_variables, inline_array, chunked_array_type, from_array_kwargs, backend_kwargs, **kwargs)
    675 decoders = _resolve_decoders_kwargs(
    676     decode_cf,
    677     open_backend_dataset_parameters=backend.open_dataset_parameters,
   (...)
    683     decode_coords=decode_coords,
    684 )
    686 overwrite_encoded_chunks = kwargs.pop("overwrite_encoded_chunks", None)
--> 687 backend_ds = backend.open_dataset(
    688     filename_or_obj,
    689     drop_variables=drop_variables,
    690     **decoders,
    691     **kwargs,
    692 )
    693 ds = _dataset_from_backend_dataset(
    694     backend_ds,
    695     filename_or_obj,
   (...)
    705     **kwargs,
    706 )
    707 return ds

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/xee/ext.py:1011, in EarthEngineBackendEntrypoint.open_dataset(self, filename_or_obj, crs, crs_transform, shape_2d, drop_variables, io_chunks, n_images, mask_and_scale, decode_times, decode_timedelta, use_cftime, concat_characters, decode_coords, primary_dim_name, primary_dim_property, ee_mask_value, request_byte_limit, ee_init_if_necessary, ee_init_kwargs, executor_kwargs, getitem_kwargs, fast_time_slicing)
   1008 else:
   1009   collection = ee.ImageCollection(self._parse(filename_or_obj))
-> 1011 store = EarthEngineStore.open(
   1012     collection,
   1013     crs=crs,
   1014     crs_transform=crs_transform,
   1015     shape_2d=shape_2d,
   1016     chunk_store=io_chunks,
   1017     n_images=n_images,
   1018     primary_dim_name=primary_dim_name,
   1019     primary_dim_property=primary_dim_property,
   1020     mask_value=ee_mask_value,
   1021     request_byte_limit=request_byte_limit,
   1022     ee_init_kwargs=ee_init_kwargs,
   1023     ee_init_if_necessary=ee_init_if_necessary,
   1024     executor_kwargs=executor_kwargs,
   1025     getitem_kwargs=getitem_kwargs,
   1026     fast_time_slicing=fast_time_slicing,
   1027 )
   1029 store_entrypoint = backends_store.StoreBackendEntrypoint()
   1031 with utils.close_on_error(store):

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/xee/ext.py:176, in EarthEngineStore.open(cls, image_collection, crs, crs_transform, shape_2d, mode, chunk_store, n_images, primary_dim_name, primary_dim_property, mask_value, request_byte_limit, ee_init_kwargs, ee_init_if_necessary, executor_kwargs, getitem_kwargs, fast_time_slicing)
    171 if mode != 'r':
    172   raise ValueError(
    173       f'mode {mode!r} is invalid: data can only be read from Earth Engine.'
    174   )
--> 176 return cls(
    177     image_collection,
    178     crs=crs,
    179     crs_transform=crs_transform,
    180     shape_2d=shape_2d,
    181     chunks=chunk_store,
    182     n_images=n_images,
    183     primary_dim_name=primary_dim_name,
    184     primary_dim_property=primary_dim_property,
    185     mask_value=mask_value,
    186     request_byte_limit=request_byte_limit,
    187     ee_init_kwargs=ee_init_kwargs,
    188     ee_init_if_necessary=ee_init_if_necessary,
    189     executor_kwargs=executor_kwargs,
    190     getitem_kwargs=getitem_kwargs,
    191     fast_time_slicing=fast_time_slicing,
    192 )

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/xee/ext.py:251, in EarthEngineStore.__init__(self, image_collection, crs, crs_transform, shape_2d, chunks, n_images, primary_dim_name, primary_dim_property, mask_value, request_byte_limit, ee_init_kwargs, ee_init_if_necessary, executor_kwargs, getitem_kwargs, fast_time_slicing)
    248 self.primary_dim_name = primary_dim_name or 'time'
    249 self.primary_dim_property = primary_dim_property or 'system:time_start'
--> 251 self.n_images = self.get_info['size']
    252 self._props = self.get_info['props']
    253 #  Metadata should apply to all imgs.

File ~/.asdf/installs/python/3.10.20/lib/python3.10/functools.py:981, in cached_property.__get__(self, instance, owner)
    979 val = cache.get(self.attrname, _NOT_FOUND)
    980 if val is _NOT_FOUND:
--> 981     val = self.func(instance)
    982     try:
    983         cache[self.attrname] = val

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/xee/ext.py:309, in EarthEngineStore.get_info(self)
    297 columns = ['system:id', self.primary_dim_property]
    298 rpcs.append(
    299     (
    300         'properties',
   (...)
    306     )
    307 )
--> 309 info = ee.List([rpc for _, rpc in rpcs]).getInfo()
    311 return dict(zip((name for name, _ in rpcs), info))

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/ee/computedobject.py:108, in ComputedObject.getInfo(self)
    102 def getInfo(self) -> Any | None:
    103   """Fetch and return information about this object.
    104 
    105   Returns:
    106     The object can evaluate to anything.
    107   """
--> 108   return data.computeValue(self)

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/ee/data.py:1080, in computeValue(obj)
   1077 body = {'expression': serializer.encode(obj, for_cloud_api=True)}
   1078 _maybe_populate_workload_tag(body)
-> 1080 return _execute_cloud_call(
   1081     _get_cloud_projects()
   1082     .value()
   1083     .compute(body=body, project=_get_projects_path(), prettyPrint=False)
   1084 )['result']

File ~/checkouts/readthedocs.org/user_builds/geetools/envs/v1.18.2/lib/python3.10/site-packages/ee/data.py:361, in _execute_cloud_call(call, num_retries)
    359   return call.execute(num_retries=num_retries)
    360 except googleapiclient.errors.HttpError as e:
--> 361   raise _translate_cloud_exception(e)

EEException: ImageCollection.mosaic: Error in map(ID=20220604T100031_20220604T100034_T32TQM):
Image.select: Band pattern 'SCL' did not match any bands. Available bands: [B1, B2, B3, B4, B5, B6, B7, B8, B8A, B9, B10, B11, B12, QA10, QA20, QA60, MSK_CLASSI_OPAQUE, MSK_CLASSI_CIRRUS, MSK_CLASSI_SNOW_ICE, CLOUD_MASK]
../../_images/e4c1e684d1cd5b3ddac7a37c3c2b5025ba754bb01dd7fee6eee1dbb748a2c4cf.png

Map RGB combo#

An RGB image is a three-band raster image that uses the red, green, and blue bands to represent the data. The following example demonstrates how to plot the RGB image using the plot function.

First create a matplotlib figure and axis. Then you can add the map to the axis. Provide a 3 elements list in the bands parameter to plot the NDVI image. As per interactive representation an image needs to be reduced to a region, here “Vatican City”. In this example we displayed the ee.FeatureCollection on top of it. Finally customize the plot.

# Create the plot figure
fig, ax = plt.subplots()

# Create the graph
image.geetools.plot(
    bands = ["B4", "B3", "B2"],
    ax=ax,
    region=vatican.geometry(),
    fc=vatican,
    color="k"
)

# as it's a figure you can then edit the information as you see fit
ax.set_title("Sentinel 2 composite in Vatican City")
ax.set_xlabel("longitude (°)")
ax.set_ylabel("latitude (°)")

plt.show()

Last updated on Dec 10, 2024.