1

I am trying to calculate NDVI and cloud pixel percentage. I have successfully done this but I am facing a problem in creating a chart of it in Jupyter Notebook, as I am new to Python so I tried various methods but no one worked.

import geopandas as gpd
import ee
import geemap
import os
import matplotlib.pyplot as plt

# Initialize Earth Engine
ee.Initialize()

# Load the shapefile using GeoPandas
nReserve = gpd.read_file('D:/test/Chichawatni.shp')

# Create a GeoJSON representation from the GeoPandas dataframe
nReserve_geojson = geemap.gdf_to_ee(nReserve)

# Create a map for displaying the results
Map = geemap.Map()

# Calculate NDVI
def calculate_ndvi(image):
    # Get the 'CLOUDY_PIXEL_PERCENTAGE' property of the image
    cloudPercentage = ee.Number(image.get('CLOUDY_PIXEL_PERCENTAGE'))

    # Calculate NDVI
    ndviImage = image.expression(
        '(NIR - RED) / (NIR + RED)',
        {
            'NIR': image.select('B8'),
            'RED': image.select('B4'),
        }
    ).float().rename('NDVI').copyProperties(image, ["system:time_start"])

    # Add the 'CLOUDY_PIXEL_PERCENTAGE' property as an image property
    return ndviImage.set('CLOUDY_PIXEL_PERCENTAGE', cloudPercentage) 
    
start_date = '2023-10-20'
end_date = '2023-10-27'

# Define the Sentinel-2 collection
sentinel2_collection = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED').filterDate(start_date, end_date)

# Filter the collection by date and AOI
filtered_collection = sentinel2_collection.filterBounds(nReserve_geojson).filterDate(start_date, end_date)

# Calculate NDVI for the filtered collection
ndvi_collection = filtered_collection.map(calculate_ndvi)

# Clip the NDVI to the shapefile
ndvi_clip = ndvi_collection.mean().clip(nReserve_geojson)

Map.centerObject(nReserve_geojson, 10)  # Center the map on the shapefile

# Add the shapefile as an image layer
nReserve_image = ee.Image().paint(nReserve_geojson, 0, 2)
Map.addLayer(nReserve_image, {'palette': 'red'}, 'Shapefile')

# Add the NDVI layer on top
ndvi_viz_params = {
    'min': -1,
    'max': 1,
    'palette': ['FFFFFF', 'CE7E45', 'DF923D', 'F1B555', 'FCD163', '99B718',
               '74A901', '66A000', '529400', '3E8601', '207401', '056201',
               '004C00', '023B01', '012E01', '011D01', '011301']
}
Map.addLayer(ndvi_clip, ndvi_viz_params, 'NDVI')


# Create a list of dates and 'CLOUDY_PIXEL_PERCENTAGE' values for the chart
def createChartData(image):
    date = ee.Date(image.get('system:time_start'))
    ndviValue = image.reduceRegion(
        reducer = ee.Reducer.mean(), 
        geometry = nReserve_geojson, 
        scale = 10,
    maxPixels= 1e13).get('NDVI')
    cloudPercentage = image.get('CLOUDY_PIXEL_PERCENTAGE')
    return ee.Feature(None, {
        'date': date,
        'NDVI': ndviValue,
        'Cloudy Percentage': cloudPercentage
    })
chartData = ndvi_collection.map(createChartData)

# Display the map with shapefile and NDVI layer
Map

1 Answer 1

0

You've only created a GEE feature collection object chartData.

To display the data as a chart, you'll first need to download the feature collection object's data locally with chartData_local = chartData.getInfo().

Then convert that to a geopandas dataframe for simple, more organised access, with chartData_organised_local = gpd.GeoDataFrame.from_features(chartData_local).

Finally, plot the geopandas frames using for example matplotlib. This is done by simply doing:

plt.subplot(2,1,1)
plt.plot(chartData_organised_local['date'],chartData_organised_local['NDVI'])
plt.ylabel('NDVI')
plt.subplot(2,1,2)
plt.plot(chartData_organised_local['date'],chartData_organised_local['Cloudy Percentage'])
plt.ylabel('Cloud Coverage')

Complete code you'll need to add at the end of yours:

chartData_local = chartData.getInfo()
chartData_organised_local = gpd.GeoDataFrame.from_features(chartData_local)
plt.subplot(2,1,1)
plt.plot(chartData_organised_local['date'],chartData_organised_local['NDVI'])
plt.ylabel('NDVI')
plt.subplot(2,1,2)
plt.plot(chartData_organised_local['date'],chartData_organised_local['Cloudy Percentage'])
plt.ylabel('Cloud Coverage')

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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