Import IMD Gridded Rainfall Data in Google Earth Engine using Google Colab (imdlib) & Code Editor
Pulakesh Pradhan
PhD Scholar, MPhil, UGC-SRF (Focus Area: Climate and Agriculture || Rural Geography)
I will demonstrate the steps to download the Indian Meteorological Department (IMD) Gridded Rainfall data as a GeoTIFF (.tif) file using imdlib (python library), and how to upload it to Google Earth Engine. Additionally, I will explain how to create a 365-day collection and merge the entire collection of multiple years into a single collection for time series analysis for a long period of time.
The Python script I have used in Google Colab, is designed to download, process, and visualize rainfall data from the India Meteorological Department (IMD) for the years 2020 to 2023 (you can change it to any year from 1901 to till date availavle). It uses the imdlib library to download and handle the IMD gridded datasets, and the rioxarray library for geospatial operations.
The script begins by installing the necessary libraries and importing them along with matplotlib.pyplot for data visualization. It then sets the start and end years for the data to be downloaded and the variable of interest, which in this case is rainfall.
The data for each year is downloaded and saved in a specified directory. For each year, the script opens the downloaded data, converts it into an xarray (a powerful data structure for multi-dimensional arrays), removes any NaN values (-999 for reinfall) , and plots the mean of the data over time. Finally, the data for each year is saved as a .tif file in the specified directory on in your local computer.
!pip install imdlib
!pip install rioxarray
import imdlib as imd
import matplotlib.pyplot as plt
start_yr = 2020
end_yr = 2023
variable = 'rain' # other options are ('tmin'/ 'tmax')
data = imd.get_data(variable, start_yr, end_yr, fn_format='yearwise')
file_dir = '/content/rain' #Path to save the files
# Loop through each year
for year in range(start_yr, end_yr+1):
# Get the data for the specific year
data = imd.get_data(variable, year, year, fn_format='yearwise')
# Open the data
data = imd.open_data(variable, year, year, 'yearwise', file_dir)
# Get the xarray
ds = data.get_xarray()
# Remove NaN values
ds = ds.where(ds['rain'] != -999.)
# Plot the data
plt.figure(figsize=(10, 6))
ds['rain'].mean('time').plot()
plt.title(f'Year: {year}')
plt.show()
# Save the data to a .tif file for the specific year
filename = f'Rain_{year}.tif'
data.to_geotiff(filename, file_dir)
Download and Upload of GeoTIFF (.tif)
Download the ‘Rain_2020.tif’, ‘Rain_2021.tif’ , ‘Rain_2022.tif’ like the files to your local computer.
Upload the downloaded ‘Rain_2020.tif’, ‘Rain_2021.tif’ , ‘Rain_2022.tif’ files to the Google Earth Engine Assets and Replace the assets id in my code to your asset ID.
Google Earth Engine: Step by Step Guide
var geometry =
ee.Geometry.Polygon(
[[[86.13219921617791, 21.416139103470776],
[86.13219921617791, 20.811464688885973],
[86.57165234117791, 20.811464688885973],
[86.57165234117791, 21.416139103470776]]], null, false);
2. Define the years and an empty array for collections:
var years = ['2020', '2021', '2022'];
var allCollections = [];
This code defines an array of years for which you want to process data. It also initializes an empty array allCollections to store the image collections for each year.
3. Loop over each year and process images:
years.forEach(function(year) {
...
});
This code uses the forEach function to loop over each year in the years array. For each year, it performs a series of operations.
4. Load the image for the year and get band names:
var y = ee.Image("projects/your-asset-id/assets/Rain_" + year); //change it to your own
var bandNames = y.bandNames();
This code loads an image from the specified path, which includes rainfall data for the given year. It then retrieves the names of the bands in the image.
5. Create an image collection from the bands:
var images = bandNames.map(function(name){
var bandImage = y.select([name]);
var index = ee.Number.parse(ee.String(name).slice(1)).subtract(1); // Use ee.String.slice
var date = startDate.advance(index, 'day');
bandImage = bandImage.set('system:time_start', date.millis());
return bandImage;
});
var collection = ee.ImageCollection.fromImages(images);
This code maps over each band name, selects the corresponding band from the image, sets the ‘system:time_start’ property for the band based on its name, and returns the modified band as an image. These images are then combined into an image collection.
6. Rename the bands and store the collection:
var renamedCollection = collection.map(function(image) {
return image.rename('b1');
});
allCollections.push(renamedCollection);
This code renames the band in each image to ‘b1’ and stores the resulting collection in the allCollections array.
7. Merge all collections into a single collection:
var mergedCollection = ee.ImageCollection(allCollections[0]);
for (var i = 1; i < allCollections.length; i++) {
mergedCollection = mergedCollection.merge(allCollections[i]);
}
This code merges all the image collections in allCollections into a single collection.
8. Print the merged collection and add it to the map:
print(mergedCollection);
Map.addLayer(mergedCollection);
This code prints the merged collection to the console and adds it as a layer on the map.
9. Create and print a chart of the image series:
var chart = ui.Chart.image.series({
imageCollection: mergedCollection.select(['b1'], ['rainfall']),
region: geometry,
reducer: ee.Reducer.mean(),
scale: 4638.3
}).setChartType('ColumnChart')
.setOptions({
title: 'IMD Daily Rainfall Time-Series',
vAxis: {title: 'Rainfall (mm)'},
hAxis: {title: '', format: 'YYYY-MMM', gridlines: {count: 12}},
series: {
0: {color: 'blue'}
},
})
// Print the chart
print(chart);
Final Timeseries Chart of Daily Rainfall in GEE
This code creates a chart of the image series in the merged collection, sets the chart type and options, and prints the chart to the console. The chart shows the mean rainfall over the specified region for each image in the collection. The images are ordered by their ‘system:time_start’ property, which was set based on the band names. This results in a time series of daily rainfall amounts.
GEE Code at One Place:
var years = ['2020', '2021', '2022'];
var allCollections = [];
years.forEach(function(year) {
var y = ee.Image("projects/use-your-asset-id/assets/Rain_" + year);
var bandNames = y.bandNames(); // Get the band names
var startDate = ee.Date(year + '-01-01'); // Set the start date
var images = bandNames.map(function(name){
var bandImage = y.select([name]);
var index = ee.Number.parse(ee.String(name).slice(1)).subtract(1); // Use ee.String.slice
var date = startDate.advance(index, 'day');
bandImage = bandImage.set('system:time_start', date.millis());
return bandImage;
});
var collection = ee.ImageCollection.fromImages(images);
var renamedCollection = collection.map(function(image) {
return image.rename('b1');
});
allCollections.push(renamedCollection);
});
// Merge all collections into a single collection
var mergedCollection = ee.ImageCollection(allCollections[0]);
for (var i = 1; i < allCollections.length; i++) {
mergedCollection = mergedCollection.merge(allCollections[i]);
}
print(mergedCollection);
Map.addLayer(mergedCollection);
var chart = ui.Chart.image.series({
imageCollection: mergedCollection.select(['b1'], ['rainfall']),
region: geometry,
reducer: ee.Reducer.mean(),
scale: 4638.3
}).setChartType('ColumnChart')
.setOptions({
title: 'IMD Daily Rainfall Time-Series',
vAxis: {title: 'Rainfall (mm)'},
hAxis: {title: '', format: 'YYYY-MMM', gridlines: {count: 12}},
series: {
0: {color: 'blue'}
},
})
// Print the chart
print(chart);
?? More insights & projects: pulakeshpradhan.github.io
Senior Research Fellow at ICAR-ATARI, Zone-VII, Barapani, Meghalaya
3 周Great work
Research Associate, Department of Civil Engineering, Indian Institute of Science
3 周Great update !