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

github github

# 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')
# 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()
# 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()
# 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()