
Time lapse Animation NDVI of Sentinel-2 using Python & Jupyter Notebook
Step 1: Install Required Libraries
# Install Libraries
!pip install earthengine-api geemap
!pip install geopandas
!pip install rasterio
!pip install imageio
!pip install numpy
!pip install matplotlib
!pip install pandas
Step 2: Authenticate and Initialize Google Earth Engine
# Import Libraries
import os
import imageio
import imageio.v2 as imageio
import numpy as np
import geopandas as gpd
import pandas as pd
import matplotlib
import matplotlib.pyplot as plt
import matplotlib.pyplot as mplot
import matplotlib.image as mpimg
import matplotlib.colors as colors
from matplotlib.colors import ListedColormap
import rasterio
from rasterio.plot import show, show_hist
import ee
import geemap
# Authenticate and initialize Earth Engine
ee.Authenticate()
ee.Initialize()
Step 3: Define ROI using shapefile
# Load the shapefile using geopandas
shapefile_path = '/home/manik/jupyter/RAJ_CC/RajCC.shp'
gdf = gpd.read_file(shapefile_path)
# Convert the geopandas GeoDataFrame to a GeoJSON string
geojson_str = gdf.to_json()
# Parse the GeoJSON string into a dictionary
geojson_dict = json.loads(geojson_str)
# Create an Earth Engine FeatureCollection from the GeoJSON dictionary
aoi_fc = geemap.geojson_to_ee(geojson_dict)
# Extract the geometry from the FeatureCollection
aoi = aoi_fc.geometry()
Step 4: Define the NDVI Calculation, Visualization Parameters & Download the NDVI Image
# Define the years for which you want to calculate NDVI
years = [2021, 2022, 2023, 2024]
# Define the date range for each year
start_date = '01-01'
end_date = '08-10'
# Define the output directory
out_dir = '/home/manik/jupyter/NDVI2'
# Create the directory if it does not exist
os.makedirs(out_dir, exist_ok=True)
# Now you can proceed with saving files to out_dir
for year in years:
# Load Sentinel-2 image collection for the specific year
image = ee.ImageCollection('COPERNICUS/S2_SR_HARMONIZED') \
.filterDate(f'{year}-{start_date}', f'{year}-{end_date}') \
.filterBounds(aoi) \
.first()
# Calculate NDVI
ndvi = image.normalizedDifference(['B8', 'B4']).rename('NDVI')
# Define the output file name
out_file = f'{out_dir}/ndvi_{year}.tif'
# Export the NDVI image
geemap.ee_export_image(ndvi.clip(aoi), filename=out_file, scale=10, region=aoi, file_per_band=False)
print(f"NDVI image for {year} saved to {out_file}")
Step 5: Verify the Download
for year in years:
out_file = f'{out_dir}/ndvi_{year}.tif'
# Open the image
with rasterio.open(out_file) as src:
ndvi_image = src.read(1)
# Display the image
plt.imshow(ndvi_image, cmap='YlGn')
plt.colorbar()
plt.title(f'NDVI {year}')
plt.show()
Step 5: Setup input and output directory for Animated NDVI
# Define the input and output directories
inDir = '/home/manik/jupyter/NDVI2'
outDir = os.path.join(os.path.dirname(inDir), 'animation')
# Create the input directory if it does not exist
if not os.path.exists(inDir):
os.makedirs(inDir)
# Change working directory to input directory
os.chdir(inDir)
# Create the output directory if it does not exist
if not os.path.exists(outDir):
os.makedirs(outDir)
Step 6: Generate NDVI Images with Custom Titles and Colormaps"
# Get list of .tif files in the current directory
fileList = [file for file in os.listdir() if file.endswith('.tif')]
for f in fileList:
lcpri_file = rasterio.open(f)
lcpri = lcpri_file.read(1)
# Use a valid colormap
cmap = 'YlGn'
cmap_reversed = matplotlib.colormaps.get_cmap('YlGn_r')
plt.figure(figsize=[20, 15])
plt.imshow(lcpri, cmap=cmap, vmin=-0.5, vmax=0.5)
# Split the filename and handle cases where "-" is not present
parts = f.split("-")
if len(parts) > 1:
fileName = parts[1][:-4]
else:
fileName = f[:-4] # Use the entire filename without extension if "-" is not present
print('Processing: {}'.format(fileName))
plt.title('NDVI ' + fileName)
cur_axes = plt.gca()
cur_axes.axes.get_xaxis().set_visible(False)
cur_axes.axes.get_yaxis().set_visible(False)
cb = plt.colorbar()
cb.set_label('NDVI Time Series', size=24)
plt.tight_layout()
plt.savefig(f'{outDir}{fileName}_NDVI.png', dpi=150)
plt.close()
Step 7: Create GIF Animation from Image Frames: Combine PNGs into Animated NDVI GIF
def make_gif(input_folder, save_filepath):
episode_frames = []
time_per_step = 0.40
for root, _, files in os.walk(input_folder):
file_paths = [os.path.join(root, file) for file in files]
file_paths = sorted(file_paths, key=lambda x: os.path.getmtime(x))
episode_frames = [imageio.imread(file_path) for file_path in file_paths if file_path.endswith('.png')]
# Convert list to numpy array (optional, only needed if further processing is required)
episode_frames = np.array(episode_frames)
# Save frames as GIF
imageio.mimsave(save_filepath, episode_frames, duration=time_per_step)
make_gif(outDir, os.path.join(outDir, "Animation_NDVI.gif"))
print("Created animation file")
Step 7: Display Generated GIF Animation in Jupyter Notebook
from IPython.display import Image, display
# Use the correct file path for the GIF
gif_path = os.path.join(outDir, 'Animation_NDVI.gif')
# Open and display the GIF
with open(gif_path, 'rb') as f:
display(Image(data=f.read(), format='gif'))
0% Positive Review (0 Comments)