Google Earth Engine seems to be most commonly used through either the Python API, or the JavaScript API on the browser. Trying to decide for one, I have come across this comparison, from a Tyler Erickson presentation:

enter image description here

While some differences are clear (e.g. many more plotting options in Python), others are more abstract to me.


  1. In practical terms, what are the advantages of being able to make a "series of calls to Earth Engine" in the Python API?
  2. Are there other differences not listed here, perhaps in regards to efficiency when exporting data, or the speed of computations?

2 Answers 2


For additional context on the slide referenced in the question, note that it is comparing using the Earth Engine Code Editor (a web IDE for developing against the Earth Engine JavaScript API) vs. using the Earth Engine Python API. The slide is from a presentation made over 3 years ago, and both the JavaScript and Python APIs have changed and the Code Editor has gained additional features such as the ability to share code between Code Editor scripts using script modules.

For Question #1:

To clarify, a series of requests can be made using either the JavaScript or Python client libraries, and also from within the Code Editor. However, working directly with the Python (or JavaScript) client library gives you more flexibility in terms of what you can do with the results. For example, you can interleave Earth Engine calls with requests to other services and use libraries not currently supported by the Code Editor development environment.

Being able to perform a series of calls facilitates the following examples:

  • Sensitivity Analyses. You can obtain data while varying one (or more) parameters, allowing you to perform a sensitivity analysis. For example, how does the changing scale parameter affect the results obtained from ee.Image.reduceRegion?
  • Series of Outputs. You can produce a series of output images, maps, or tables. For example, you could generate a cloud-free image for every watershed in a country.
  • Jupyter Notebooks. You can develop workflows/tutorials that display intermediate results. For example, see the Jupyter/Colab notebook linked from this tutorial.

For Question #2:

  • There certainly are other differences beyond the simple list shown on the slide, such as some differences in syntax. Another is that the Earth Engine Code Editor allows developers to easily publish hosted applications (Earth Engine Apps), which would require significantly more work to do the same using the Python API.
  • Both the JavaScript and Python APIs utilize a lower-level REST API for computations performed on the Earth Engine backend servers, so there is no computational or export performance benefit of using one over the other.

Using Python can be easier if we convert some of the Java examples of GEE to Python.

SO, this is possible with geemap:

sudo pip3 install geemap

and clone the repo:

sudo git clone https://github.com/giswqs/geemap.git

cd /geemap/examples/python

sudo nano javascript_to_python.py

sudo python 3 javascript_to_python.py

will run an edited file for your own java/js directory and create both workable python scripts and ipynb files for each java/js file in the directory.

I used this to convert goes16 example on GEE from Java to Python. I also added a little code to the output to include a Folium Display.

import subprocess
import ee
import geemap
import folium

# %%
#Map = geemap.Map(center=[40, -100], zoom=4)

# Add Earth Engine dataset
# Band aliases.
BLUE = 'CMI_C01'
RED = 'CMI_C02'
GREEN = 'GREEN'; # 16 pairs of CMI and DQF followed by Bah 2018 synthetic green. # Band numbers in the EE asset, 0-based.
NUM_BANDS = 33; # Skipping the interleaved DQF bands.
BLUE_BAND_INDEX = (1 - 1) * 2
RED_BAND_INDEX = (2 - 1) * 2
VEGGIE_BAND_INDEX = (3 - 1) * 2
GREEN_BAND_INDEX = NUM_BANDS - 1; # Visualization range for GOES RGB.
GOES_MIN = 0.0
GOES_MAX = 0.7; # Alternatively 1.0 or 1.3.
GAMMA = 1.3
goesRgbViz = {
'bands': [RED, GREEN, BLUE],
'min': GOES_MIN,
'max': GOES_MAX,
'gamma': GAMMA
def applyScaleAndOffset(image):
image = ee.Image(image)
bands = Array(NUM_BANDS)
for i in range(1, 17, 1):
bandName = 'CMI_C' + (100 + i + '').slice(-2)
offset = ee.Number(image.get(bandName + '_offset'))
scale = ee.Number(image.get(bandName + '_scale'))
bands[(i-1) * 2] = image.select(bandName).multiply(scale).add(offset)
dqfName = 'DQF_C' + (100 + i + '').slice(-2)
 bands[(i-1) * 2 + 1] = image.select(dqfName)

  # Bah, Gunshor, Schmit, Generation of GOES-16 True Color Imagery without a
 # Green Band, 2018. https:#doi.Org/10.1029/2018EA000379
 # Green = 0.45 * Red + 0.10 * NIR + 0.45 * Blue
green1 = bands[RED_BAND_INDEX].multiply(0.45)
green2 = bands[VEGGIE_BAND_INDEX].multiply(0.10)
green3 = bands[BLUE_BAND_INDEX].multiply(0.45)
green = green1.add(green2).add(green3)
bands[GREEN_BAND_INDEX] = green.rename(GREEN)
return ee.Image(ee.Image(bands).copyProperties(image, image.propertyNames()))

collection = 'NOAA/GOES/16/MCMIPF/'
imageName = '2020210184019900000'
assetId = collection + imageName
image = applyScaleAndOffset(assetId)


#Map.addLayer(image, goesRgbViz)

#Map.addLayerControl()  # This line is not needed for ipyleaflet-based Map.




my_map = folium.Map(location=[34, -118], zoom_start=12, height=500, control_scale=True)
my_map.add_ee_layer(dem.updateMask(dem.gt(0)), goesRgbViz, 'DEM')
# Add a layer control panel to the map.
outHtml = '/var/www/map.html' # temporary file path, change if needed my_map.save(outHtml) 

#if running the script on the web via cgi, then use below to visualize in web @ url
#print ('<section> <div id="container"> <iframe id="embed" scrolling="no" src="/map.html"></iframe> </div></section>')

Not the answer you're looking for? Browse other questions tagged or ask your own question.