Using Mapbox and GDAL to Visualize Trends in

Ocean Phytoplankton from NASA Earth Observations Satellite Images

Presented at FOSS4G 2017 Boston, August 16, 2017

Command Line Cartography

eπ Maps — Offline Maps for Mobile



ePi Rational, Inc.


Oceaneos Marine Research Foundation

"Adding nutrients to a depleted marine ecosystem.""

Icelandic Volcano

NASA Earth Observations (NEO)

"One of the best places to study Earth is from space.""

"NASA satellites continually orbit the globe, collecting information about Earth’s ocean, atmosphere, and land surfaces.""

"Satellites can even monitor the activity of life forms, such as phytoplankton, from their remote vantage points.""

"NEO is part of the EOS Project Science Office located at NASA Goddard Space Flight Center.""


NEO Data Available

Architecture - Use to Tile 0.1° GeoTIFFs

gdal_translate -of vrt file.tif out.vrt -z 0-6 -f PNG out.vrt out

source — GDAL2Tiles

Geo-Imaging pipeline


Image Healing

G'MIC inpaint

gmic kindlmann-MY1DMM_CHLORA_2016-01.tif -to_colormode 3 \
  bathy.3600x1800.threshold.png \
  -blend xor \
  --select_color[0] 0,0,0,0 \
  -inpaint[0] [1],0 \
  -o result.png

Color Lookup Tables (cLUT)

8-bit Index GeoTIFF

8-bit = 256 color levels

Color Lookup Table for 8-bit Index GeoTIFF

gdal_translate -of VRT MY1DMM_CHLORA_2016-07-01_rgb_3600x1800.TIFF clut.vrt

# edit the clut.vrt to make blue2red, or any other color LUT

# cp clut.vrt clut.blue2red.vrt
gdal_translate clut.blue2red.vrt MY1DMM_CHLORA_2016-07-01_rgb_3600x1800.clut.blue2red.TIFF

Color Advice

Overlay over Google Mapbox

Chlorophyll over Mapbox Satellite

Done once ... now scale

Upload a MBTile to

Image Compression

GDAL drivers to the rescue

Solution WebP


gdal_translate -of vrt file.tif out.vrt -z 0-6 -f WEBP out.vrt out


Time Series

NEO Data Available

Floating Point data

NumPy for Data Analysis

float = gdal.Open('MY1DMW_CHLORA_2016-09-05.FLOAT.TIFF')
f = numpy.array(float.GetRasterBand(1).ReadAsArray())
grid = numpy.meshgrid(f)

# Extract chlorophyll less than 1.0
t = numpy.less (grid , 1.0)
choice = numpy.logical_and(t , grid)
lowPlankton = numpy.extract(choice, grid)

Displaying the Time series


Visualizing and laying out time-series data built on D3.js

D3.js charting for science

The Oceaneos Global Chlorophyll Map

Summary — Maps tell stories

Summary of Tools

Text & Online Resources

Thank You‼️



Vector Approach

Scaling WebP