One easier way I found on one of the tutorials exports all the pixels out directly in Python very rapidly (see https://developers.google.com/earth-engine/tutorials/community/intro-to-python-api-guiattard). The logic goes:
- Define area of interest using a
ee.Geometry()
object
- Perform "clipping" by doing
collection.getRegion(geometry, scale=4000).getInfo()
. Note that I inputted scale=4000
to reduce the resolution, which you can also just ignore if you need the original image pixels. This returns a python list like this:
,
['2003_09_14',
-92.86783407227614,
42.059121602476,
1063497600000,
5729,
3067],
...]
- Using the
ee_array_to_df()
, you can turn this long list into a data frame, which you could then save as a csv. This is more efficient in my opinion if you are planning to save multiple images (at different locations and times) at the same time.
Minimum working example attached
import pandas as pd
import matplotlib.pyplot as plt
import ee
# Trigger the authentication flow.
ee.Authenticate()
# Initialize the library.
ee.Initialize()
def ee_array_to_df(arr, list_of_bands):
"""Transforms client-side ee.Image.getRegion array to pandas.DataFrame.
Modification of
https://developers.google.com/earth-engine/tutorials/community/intro-to-python-api-guiattard
"""
df = pd.DataFrame(arr)
# Rearrange the header.
headers = df.iloc[0]
df = pd.DataFrame(df.values[1:], columns=headers)
# Remove rows without data inside.
df = df[['longitude', 'latitude', 'time', *list_of_bands]].dropna()
# Convert the data to numeric values.
for band in list_of_bands:
df[band] = pd.to_numeric(df[band], errors='coerce')
# Convert the time field into a datetime.
df['datetime'] = pd.to_datetime(df['time'], unit='ms')
# Keep the columns of interest.
df = df[['datetime', "longitude", "latitude", *list_of_bands]]
return df
bands = ["NDVI", "EVI"]
date_start = "2003-04-01"
date_end = "2003-10-31"
collection = ee.ImageCollection("MODIS/006/MOD13Q1").filterDate(
ee.Date(date_start), ee.Date(date_end)
).select(bands)
# this could also be user-defined
geometry = ee.Geometry.Polygon(
[[[-92.9341420641855, 42.67007391984631],
[-92.9341420641855, 41.94316737537707],
[-92.0407572499231, 41.94316737537707],
[-92.0407572499231, 42.67007391984631]]])
# now perform the clipping and dataframe conversion
collection_area_of_interest = collection.getRegion(geometry, scale=4000).getInfo()
df_area_of_interest = ee_array_to_df(collection_area_of_interest, bands)
# to give you a preview
# df_area_of_interest.head()
# Plot the spatial map using the latitude and longitude (in practice, you need to pick specific date by doing df_area_of_interest[df_area_of_interest["datetime"]=="2003-06-10"]
plt.scatter(df_area_of_interest["longitude"], df_area_of_interest["latitude"], c=df_area_of_interest["NDVI"])
plt.colorbar()
