I have written a short program in Python to extract a time series for any given pixel for MODIS data stored in the Google Earth Engine. The code is working fine and returns a data frame containing the relevant band value and date.
import pandas as pd import numpy as np from datetime import datetime as dt import ee def extract_time_series(lat, lon, start, end, product_name, band_name, sf): # Set up point geometry point = ee.Geometry.Point(lon, lat) # Obtain image collection for all images within query dates coll = ee.ImageCollection(product_name)\ .filterDate(start, end) # Get list of images which correspond with the above images = [item.get('id') for item in coll.getInfo().get('features')] store =  date_store =  # Loop over all images and extract pixel value for image in images: im = ee.Image(image) # Obtain date from timestamp in metadata date = dt.fromtimestamp(im.get("system:time_start").getInfo() / 1000.) date_store.append(np.datetime64(date)) # Extract pixel value data = im.select(band_name)\ .reduceRegion(ee.Reducer.first(), point, 1)\ .get(band_name) store.append(data.getInfo()) # Scale the returned data based on scale factor store = [x * sf if isinstance(x, int) else np.nan for x in store] # Convert output into pandas data frame df = pd.DataFrame(index=date_store, data=store, columns=[band_name]) return df if __name__ == "__main__": ee.Initialize() latitude = 9.95 longitude = -10.09 start_date = '2018-01-01' end_date = '2018-01-31' product = 'MODIS/006/MOD11A1' band = 'LST_Day_1km' scale_factor = 0.02 # Extract data and obtain pd.DataFrame output = extract_time_series(latitude, longitude, start_date, end_date, product, band, scale_factor)
However, I am aware of the way GEE handles reducing regions and how it can sometimes be difficult to know precisely what is happening. I decided to compare my extract MODIS values with the same time series requested from AppEEARS.
I noticed that the values are different and thus my code must be performing some spatial average, probably during the:
data = im.select(band_name)\ .reduceRegion(ee.Reducer.first(), point, 1)\ .get(band_name)
line. I set scale == 1 here so that the returned value I receive should be equal to the value at the native resolution (info on this).
Can anyone shed any light on how I can extract the MODIS band value for ONLY my point of interest? Any amendments to the code is also very welcome!