How can a sea disappear? Case study of the Aral Sea using Python and MODIS data.

Let’s create a timelapse and check if it’s true!

Aleksei Rozanov
5 min readMar 6, 2024
Photo by Artem Asset on Unsplash

Can you imagine that a SEA disappears because of human actions? Sounds like an excellent catch for a film, but, unfortunately, it’s the reality. Once in the Central East there was the Aral Sea, lying between modern Kazakhstan and Uzbekistan. During the 20th century the territories of both of these countries were the Soviet Union republics, and back then the Soviet scientists wanted to farm cotton, rice, cereals and other plants in these areas, so they undertook a large irrigation project. Shortly speaking, they cut off two major rivers, flowing into the sea, so since the 1960s the Aral Sea started its shrinking. Numbers tell us that by 2007 the sea has shrunk to 10% of its original size.

Image from Britannica.

It is a truly illustrative example of how the reckless usage of natural resources can be a cause of irreversible changes in ecosystems. That’s why I decided to investigate myself the dynamic of the Aral Sea region over last 23 years, and the current article will have two aims: raise the awareness of this problem and share a tutorial on how to create an animated representation of satellite imagery using Google Earth Engine (GEE) and python. As usually, you can find all the code lines on my github.

Image by Trent Nelson on Sltrib.

To follow up with my steps you’ll need to install geemap and ee libraries. If you want to know more about them, check my another article.

So let’s do our imports for this task:

import pandas as pd
import numpy as np
import datetime
import matplotlib.pyplot as plt
import ee
import geemap

from os import listdir
from os.path import join
import os

Then you’ll need to authenticate your Google credentials to use GEE:

ee.Authenticate()
ee.Initialize()

Now let’s set our spatiotemporal info. In this case I decided to get the images of the multispectral radiometer called MODIS Terra for the period of 2000–2023. For each year we will acquire an image for the 1st of August. To slice the region let’s specify the center at 45°N 60°E and take a circle around it with radius equal to 5000 m.

startDate = pd.to_datetime('2000-08-01')
endDate = pd.to_datetime('2023-08-01')
dates_list = pd.date_range(start='2000-08-01', freq='AS-AUG', periods=24)

lat, lon = 45,60
point = ee.Geometry.Point([lon, lat]).buffer(distance=5000)

Now let’s collect the data. Here we create a python list of GEE image collections.

IMGS = list()
for date in dates_list:
MOD = ee.ImageCollection("MODIS/061/MOD09GA")\
.filterDate(start = date)\
.filterBounds(point)
IMGS.append(ee.Image(MOD.first()))

Now, when we have our data, let’s talk about the spectral bands. MODIS has more than 30 bands in visual and IR parts of spectrum with different spatial resolution. But for our purposes it’ll be enough to have 3 bands (Red, Green and Blue — RGB) to create a visual representation. That’s why I picked MOD09GA product. Its resolution is 500 m, i.e. each pixel of the image has height and width of 500 m.

So let’s specify the bands of our interest:

bands = ['sur_refl_b02', 'sur_refl_b04', 'sur_refl_b03'] #RGB

Now we can create an interactive map with one of the images. Let’s do that!
Firstly, we set up an empty map with a center at the Aral Sea. Then we specify the region of our interest, i.e. a big rectangle around the center. After that, we simply add a layer to our map with the selected bands clipped for the selected region:

map = geemap.Map(center=[lat, lon], zoom=8)
roi = ee.Geometry.Rectangle([57, 43,62, 47])
pars = {'min': -100.0,
'max': 8000.0,} #I took this values from the meta data, you can do the same
#by IMGS[0].getInfo()
map.add_ee_layer(IMGS[0].select(bands).clip(roi), pars)
map
Image by author.

As you can see we successfully pre-processed the data, so now our goal is to get a timelapse, and to do that, we’ll be using great geemap library extensively. Firstly, let’s create a timeseries of the images:

col = geemap.create_timeseries(
ee.ImageCollection(IMGS), #it's necessary to convert our list to collection
'2000-08-01',
'2023-08-01',
region=roi,
bands=bands,
)

Now we need to convert our data to 8-bit RGB images to later save them as jpg files:

col = col.select(bands).map( #we use map function to apply it to all imgs
lambda img: img.visualize(**pars).set(
{
"system:time_start": img.get("system:time_start"),
"system:date": img.get("system:date"),
}
)
)

It’s time to set meta-parameters for our future gif. They are arbitrary, so you can set your own:

video_args = {}
video_args["dimensions"] = 768
video_args["region"] = roi
video_args["framesPerSecond"] = 30
video_args["crs"] = "EPSG:3857"
video_args["min"] = 0
video_args["max"] = 255
video_args["bands"] = ["vis-red", "vis-green", "vis-blue"]

And the final piece of code is most complex one. The first part of the code is basically creating a folder called MOD to save yearly images in .jpg format. The second big part is the get_image_collection_thumbnails function which creates and saves regular .jpg images to our MOD directory. The third stage is the make_gif function which assess MOD dir, takes all the images and creates a gif. After running, it automatically cleans MOD folder. And finally, the last element of our code is adding dates and a progress bar to the created gif.

'''Names'''
out_dir=''
count = col.size().getInfo()
basename = 'MOD'
names = [
os.path.join(
out_dir, f"{basename}_{str(i+1).zfill(int(len(str(count))))}.jpg"
)
for i in range(count)
]

'''Creating and saving imgs'''
geemap.get_image_collection_thumbnails(
col,
'./MOD',
vis_params={
"min": 0,
"max": 255,
"bands": video_args["bands"],
},
dimensions=768,
names=names,
)

'''Creating a gif'''
geemap.make_gif(
['./MOD/'+x for x in names],
'MOD.gif',
fps=2,
mp4=False,
clean_up=True,
)

'''Adding dates and a progress bar'''
geemap.add_text_to_gif(
'MOD.gif',
'MOD.gif',
text_sequence=[x.strftime('%Y-%m-%d') for x in dates_list],
font_type='monospace',
font_size=24,
font_color='white',
duration=1000 / 3,

)

Here it is, our beautiful timelapse:

Image by author.

Hope you enjoyed, and the article was helpful and insightful!

===========================================

All my publications on Medium are free and open-access, that’s why I’d really appreciate if you followed me here!

P.s. I’m extremely passionate about (Geo)Data Science, ML/AI and Climate Change. So if you want to work together on some project pls contact me in LinkedIn.

🛰️Follow for more🛰️

--

--

Aleksei Rozanov

🎓 M.s. Big Data and ML | 👩🏻‍💻AI/ML + 🌍 Geo data + 🛰️Remote sensing