A brief rundown of creating rasters and compiling them into an animated gif entirely in python
The goal here is to rasterize the contents of a netCDF file containing global sea ice concentrations in October from 1981 to 2020, and then compile each of those rasters into a single gif.
import xarray as xr
import rasterio as rio
import pandas as pd
from rasterio.plot import show
import matplotlib.pyplot as plt
import rioxarray
import imageio
These data are a small subset I created of the Merged Hadley-OI sea surface temperature and sea ice concentration dataset. We’ll read them in as an xarray
dataset.
= xr.open_dataset("data/noaa_ice_81-20.nc") ice
Becuase we’re working with spatial data, we need to set the coordinate reference system (CRS) and specify our spatial dimensions—in this case: lon
and lat
.
= ice.rio.write_crs(4326, inplace=True)
ice
= ice['SEAICE'].rio.set_spatial_dims('lon', 'lat')
ice
= ice.rename({'lat':'latitude', 'lon':'longitude'}) ice
Here we create a loop that exports the sea ice data from each year as a tiff using rasterio.to_raster()
, renders it (quietly) with pyplot.imshow()
, and then saves the formatted image as a png with pyplot.savefig()
. An important part of the formatting portion of the loop is titling each image with its corresponding year: plt.title(years[i])
.
= range(1981, 2021)
years
= [] rasters
for i in range(0, len(ice)):
= ice[i]
ice_i
= 'Data/noaa_ice_' + str(years[i]) + '.tif'
tiff
ice_i.rio.to_raster(tiff)
# opening the tiff we just exported
= rio.open(tiff)
open_rast
# reading the first (and only) band within the raster
= open_rast.read(1)
read_rast
# preventing matplotlib from displaying every image
plt.ioff()
=False)
plt.figure(frameon
plt.imshow(read_rast,='lower',
origin='Blues_r',
cmap=[-180, 180, -90, 90])
extent
plt.title(years[i])=False, bottom=False)
plt.tick_params(left
plt.xticks([])
plt.yticks([])
plt.tight_layout()
= tiff + ".png"
png
# save the figure we just created with a resolution of 200 dpi
=200)
plt.savefig(png, dpi
plt.close()
# compiling a list of the file names for the next step
rasters.append(png)
Lastly we’ll use the imageio
library to create the final animation. To do this, we iterate through the list of png files we created in the last loop, reading each of them in using imageio.imread()
and compiling them into a new list. We then feed that list into imageio.mimsave()
which aggregates and exports the images as a gif. The default frame rate is quite fast, so we can increase the duration
to 0.5 seconds to make the animation a bit more digestible.
= []
png_imageio
for file in rasters:
file))
png_imageio.append(imageio.imread(
'Data/ice_81_20.gif', png_imageio, **{'duration':0.5}) imageio.mimsave(
For attribution, please cite this work as
Menzies (2021, Dec. 20). Peter Menzies: Creating an animated visualization of sea ice concentration with imageio. Retrieved from https://petermenzies.github.io/posts/2021-12-20-sea-ice-animation/
BibTeX citation
@misc{menzies2021creating, author = {Menzies, Peter}, title = {Peter Menzies: Creating an animated visualization of sea ice concentration with imageio}, url = {https://petermenzies.github.io/posts/2021-12-20-sea-ice-animation/}, year = {2021} }