Examples of how to work between GEE and Pandas¶
Copyright 2025 Ian Housman
Licensed under the Apache License, Version 2.0 (the “License”); you may not use this file except in compliance with the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License.
Example of the functionality of gee2Pandas module
Use this module to go between local data and GEE for more general data science/statistical analysis
# Import Modules
try:
import geeViz.getImagesLib as gil
except:
!python -m pip install geeViz
import geeViz.getImagesLib as gil
import geeViz.foliumView as fv
import geeViz.gee2Pandas as g2p
import pandas as pd
import matplotlib.pyplot as plt
import numpy
ee = fv.ee
# Choose whether to use Folium-based map or geeView (syntax remains the same)
# Map = fv.foliumMapper()
Map = gil.Map
Map.port = 1233
print('done')
Initializing GEE
Cached project id file path: C:\Users\ihousman\.config\earthengine\credentials.proj_id
Cached project id: lcms-292214
*** Earth Engine *** Share your feedback by taking our Annual Developer Satisfaction Survey: https://google.qualtrics.com/jfe/form/SV_0JLhFqfSY1uiEaW?source=Init
Successfully initialized
geeViz package folder: c:\Users\ihousman\AppData\Local\Programs\Python\Python311\Lib\site-packages\geeViz
PyTables is not installed. No support for HDF output.
done
# Set up study area and bring in some Sentinel 2 data for pre and post years
Map.clearMap()
# Map.setMapArg('tiles',"cartodb positron")
studyArea = ee.Geometry.Polygon(
[[[-113.21807278537877, 41.786028237932015],
[-113.21807278537877, 40.595571243156144],
[-111.82280911350377, 40.595571243156144],
[-111.82280911350377, 41.786028237932015]]], None, False)
preYear = 2022
postYear = 2023
startJulian = 160
endJulian = 190
s2s = gil.getProcessedSentinel2Scenes(studyArea,preYear-1,postYear+1,startJulian,endJulian)
post = s2s.filter(ee.Filter.calendarRange(postYear,postYear,'year')).median()
postWater = gil.simpleWaterMask(post).rename(['Water'])
post = post.addBands(postWater)
Map.addLayer(post,gil.vizParamsFalse,'S2 Median {}'.format(postYear),False)
Map.addLayer(postWater,{'palette':'888,00F'},'S2 Water {}'.format(postYear))
pre = s2s.filter(ee.Filter.calendarRange(preYear,preYear,'year')).median()
preWater = gil.simpleWaterMask(pre).rename(['Water'])
pre = pre.addBands(preWater)
waterTransitionClasses=preWater.add(1).multiply(10).add(postWater).rename('Water_Transition_{}-{}'.format(preYear,postYear))
Map.addLayer(waterTransitionClasses,{'min':1,'max':21,'palette':'0F0,00F'},'Water_Transition_{}-{}'.format(preYear,postYear))
Map.addLayer(pre,gil.vizParamsFalse,'S2 Median {}'.format(preYear))
Map.addLayer(preWater,{'palette':'888,00F'},'S2 Water {}'.format(preYear))
Map.centerObject(studyArea)
Map.addLayer(studyArea,{'strokeColor':'F00','strokeWidth':10},'Study Area')
# print(Map.mapArgs)
Map.view()
Get Processed Sentinel2:
Start date: Jun 09 2021 , End date: Jul 08 2024
Using S2 Collection: COPERNICUS/S2_HARMONIZED
Joining pre-computed cloudScore+ from: GOOGLE/CLOUD_SCORE_PLUS/V1/S2_HARMONIZED
Setting to aggregate instead of resample
Converting S2 data to daily mosaics
Applying cloudScore+
Adding layer: S2 Median 2023
Adding layer: S2 Water 2023
Adding layer: Water_Transition_2022-2023
Adding layer: S2 Median 2022
Adding layer: S2 Water 2022
Adding layer: Study Area
Starting webmap
Using default refresh token for geeView
Starting local web server at: http://localhost:1233/geeView/
HTTP server command: "c:\Users\ihousman\AppData\Local\Programs\Python\Python311\python.exe" -m http.server 1233
Done
cwd a:\GEE\gee_py_modules_package\geeViz\examples
geeView URL: http://localhost:1233/geeView/?projectID=lcms-292214&accessToken=ya29.a0AeDClZC7rbMaygDhJcMEQ0u5_tqi4RCJz5duLi9eQYcy-Zzhz3T9dcmPOnEuD0NwEy27M9Wnr2GSc0ECMwXaMemmVP2iroa_MGOFvl4Jp5RU4pA_zrwQ4C3d28ntB0uOzARn-lg_onfuT40HjsqVZRaofbnYbto04qT8lqbp4P0aCgYKAQ0SARESFQHGX2MiU_0uj5D6U3SDTAv6wwgP7A0178&accessTokenCreationTime=1732565631149
# Format a stack raster and get a csv local table
nSamples = 500
Map.clearMap()
preBns = pre.bandNames().map(lambda bn:ee.String(bn).cat('_yr{}_jd{}-{}'.format(preYear,startJulian,endJulian)))
postBns = post.bandNames().map(lambda bn:ee.String(bn).cat('_yr{}_jd{}-{}'.format(postYear,startJulian,endJulian)))
stack = pre.rename(preBns).addBands(post.rename(postBns)).addBands(waterTransitionClasses)
sample =ee.FeatureCollection.randomPoints(studyArea, nSamples, 0, 50)
Map.addLayer(sample.map(lambda f:ee.Feature(f).buffer(10).bounds()),{},'Sample')
outDir = '/tmp'
if not g2p.os.path.exists(outDir):g2p.os.makedirs(outDir)
out_csv = g2p.os.path.join(outDir,'gee2Pandas_test_csv.csv')
g2p.geeToLocalZonalStats(sample,stack,out_csv,reducer=ee.Reducer.first(),scale=10,crs='EPSG:5070',transform=None,tileScale=4,overwrite=False,maxNumberOfFeatures=5000)
Map.view()
Adding layer: Sample
/tmp\gee2Pandas_test_csv.csv already exists
Starting webmap
Using default refresh token for geeView
Local web server at: http://localhost:1233/geeView/ already serving.
cwd a:\GEE\gee_py_modules_package\geeViz\examples
geeView URL: http://localhost:1233/geeView/?projectID=lcms-292214&accessToken=ya29.a0AeDClZA_pdYBT8Da3RV0VuNIO82RcHCoJBkvgRzVPbMvNB7-Nymd8Z0PytK-lQbvzobDzcQ0mw8Gic89IlORedmyBcpl7W-V6L0lPtE-sX94emQUnKtxAr5IkIFinQiHPrJscFcVfvQ9jlO9DOwcmFTGAnWYk7QK6wcDXohDsIMaCgYKAYcSARESFQHGX2MiRPp-2OrqyFbvRcc9_zvJlg0178&accessTokenCreationTime=1732565635250
# Visualize xy scatter of pre and post years for some bands
t = pd.read_csv(out_csv)
plotBandNames = ['NBR','NDMI']
for plotBandName in plotBandNames:
preColumn = '{}_yr{}_jd{}-{}'.format(plotBandName,preYear,startJulian,endJulian)
postColumn = '{}_yr{}_jd{}-{}'.format(plotBandName,postYear,startJulian,endJulian)
waterColumn = 'Water_yr{}_jd{}-{}'.format(postYear,startJulian,endJulian)
# display(t)
columns = t.columns
fig, ax = plt.subplots()
scat = ax.scatter(t[preColumn],t[postColumn],c=t[waterColumn],alpha=0.2)
ax.set_xlabel(preColumn)
ax.set_ylabel(postColumn)
plt.show()


# Now go from a local csv to a GEE featureCollection
fc = g2p.tableToFeatureCollection(out_csv)
Map.clearMap()
Map.addLayer(fc,{'styleParams':{'pointSize':2,'color':'0DF'}},'Test Sample')
Map.turnOnInspector()
Map.centerObject(fc)
Map.view()
Adding layer: Test Sample
Starting webmap
Using default refresh token for geeView
Local web server at: http://localhost:1233/geeView/ already serving.
cwd a:\GEE\gee_py_modules_package\geeViz\examples
geeView URL: http://localhost:1233/geeView/?projectID=lcms-292214&accessToken=ya29.a0AeDClZDuAuuThPvzPHAPlCNFGvzYQShuqqqN0i2vdB4dxVkn1LYXnb42sCaCBoboFD4-SYtRTg1kkmK-aWFKssUhmA-E9PQyXyR4Za3sVJnaEalIHtgYvLXkQ1DOYmFybz6cEMDntPVHLX30KagvUS0Kw0-aPPMUneuEG2gwJz0aCgYKATMSARESFQHGX2MiuDZhAcXWgIBJLVWdu6OINQ0178&accessTokenCreationTime=1732565803239