speciesgrids is a cloud-optimized gridded dataset of WoRMS-aligned marine species distributions based on the OBIS and GBIF occurrence snapshots. The dataset is available in GeoParquet and currently supports Geohash and H3 grid output.
This repository contains the Python code that generates the speciesgrids product, along with its documentation, a web viewer, and usage examples. The dataset itself is not stored in this repository. You can explore how to access and use this product here. You can also check the notebooks, with examples of use in Python and R.
When using this data product, please copy the citations provided below. The first cites the dataset, the second the code that builds it, and the rest the source data:
OBIS (2025). speciesgrids: gridded dataset of marine species occurrence (H3 resolution 7). Ocean Biodiversity Information System. Intergovernmental Oceanographic Commission of UNESCO. Available at s3://obis-products/speciesgrids/h3_7/
Provoost, P. (2026). speciesgrids: build pipeline and documentation for a gridded dataset of marine species occurrence. Zenodo. https://doi.org/10.5281/zenodo.19392660
GBIF.org (1 May 2024) GBIF Occurrence Data https://doi.org/10.15468/dl.ubwn8z
OBIS (25 October 2023) OBIS Occurrence Snapshot. Ocean Biodiversity Information System. Intergovernmental Oceanographic Commission of UNESCO. https://obis.org.
World Register of Marine Species. Available from https://www.marinespecies.org at VLIZ. Accessed 2024-05-01. doi:10.14284/170.
IUCN. 2023. The IUCN Red List of Threatened Species. Version 2023-1. https://www.iucnredlist.org. Accessed on 13 May 2024.
Gearty W, Chamberlain S (2022). rredlist: IUCN Red List Client. R package version 0.7.1, https://CRAN.R-project.org/package=rredlist.
An h3 grid at resolution 7 is available for download from S3. Resolution can easily be scaled down (i.e. cells made larger) via freely available h3 tools.
aws s3 cp --recursive s3://obis-products/speciesgrids/h3_7 . --no-sign-requestYou can explore the data in the S3 bucket with AWS CLI:
aws s3 ls --no-sign-request --recursive s3://obis-products/speciesgrids/
2024-05-13 03:47:36 0 speciesgrids/
2025-04-27 06:40:57 58943 speciesgrids/h3_7/000
2025-04-27 06:40:58 34851 speciesgrids/h3_7/001
2025-04-27 06:40:58 2245913 speciesgrids/h3_7/002
2025-04-27 06:40:58 693297 speciesgrids/h3_7/003
...
The 64 files in h3_7/ are partitioned by Bing Maps quadkey at zoom level 3, with each filename (e.g. 032) corresponding to the quadkey of its tile. You could use this to selectively access specific regions of the globe. In practice, however, the full dataset is only ~600 MiB, so it's usually simpler to download the whole GeoParquet and query it locally with DuckDB. If you are working in a cloud environment, querying the GeoParquet file directly might also make sense. But for repeated querying, a local copy is probably most efficient.
Each parquet file contains the following columns:
| Column | Type | Description |
|---|---|---|
cell |
string | Uber H3 cell index at resolution 7, as a 15-character hexadecimal string. |
species |
string | Accepted scientific name at species rank, from WoRMS taxonomy. |
AphiaID |
int32 | WoRMS persistent taxonomic identifier. Resolvable at https://www.marinespecies.org/aphia.php?p=taxdetails&id={AphiaID}. |
records |
int64 | Count of underlying OBIS and GBIF occurrence records aggregated into this (cell, species) tuple. |
min_year |
int64 | Earliest observation year among the aggregated records. NULL if no underlying record carries a year. |
max_year |
int64 | Latest observation year among the aggregated records. NULL if no underlying record carries a year. |
source_obis |
boolean | True if at least one underlying record originated from OBIS. |
source_gbif |
boolean | True if at least one underlying record originated from GBIF. |
kingdom |
string | Taxonomic kingdom, from WoRMS accepted taxonomy. May be NULL where the source taxonomy is incomplete. |
phylum |
string | Taxonomic phylum, from WoRMS accepted taxonomy. |
class |
string | Taxonomic class, from WoRMS accepted taxonomy. |
order |
string | Taxonomic order, from WoRMS accepted taxonomy. |
family |
string | Taxonomic family, from WoRMS accepted taxonomy. |
genus |
string | Taxonomic genus, from WoRMS accepted taxonomy. |
category |
string | IUCN Red List threat status, populated only for threatened or extinct categories (VU, EN, CR, EX, EW). NULL for unassessed species or species in other categories such as Least Concern. |
geometry |
geometry | Centroid of the H3 cell as a Point geometry in WGS 84 (EPSG:4326), encoded per the GeoParquet specification. |
This example uses a local copy of the dataset to explore the distribution of Gadus species.
import geopandas
import lonboard
import seaborn as sns
filters = [("genus", "==", "Gadus")]
gdf = geopandas.read_parquet("../h3_7/", filters=filters)[["cell", "records", "geometry", "species"]]
def generate_colors(unique_species):
palette = sns.color_palette("Paired", len(unique_species))
rgb_colors = [[int(r*255), int(g*255), int(b*255)] for r, g, b in palette]
color_map = dict(zip(unique_species, rgb_colors))
colors = lonboard.colormap.apply_categorical_cmap(gdf["species"], color_map)
return colors
point_layer = lonboard.ScatterplotLayer.from_geopandas(gdf)
point_layer.get_radius = 10000
point_layer.radius_max_pixels = 2
point_layer.get_fill_color = generate_colors(gdf["species"].unique())
lonboard.Map([point_layer])This spatially queries the GeoParquet dataset on AWS using a WKT geometry.
library(duckdb)
library(DBI)
library(dplyr)
library(jsonlite)
library(glue)
library(stringr)
# Read WKT from https://wktmap.com/?e6b28728
wkt <- fromJSON("https://xpjpbiqaa3.execute-api.us-east-1.amazonaws.com/prod/wkt/e6b28728")$wkt %>%
str_replace("<.*?>\\s", "")
# Set up duckdb connection and extensions
con <- dbConnect(duckdb())
dbSendQuery(con, "install httpfs; load httpfs;")
dbSendQuery(con, "install spatial; load spatial;")
# Query
species <- dbGetQuery(con, glue("
select kingdom, phylum, class, family, genus, species, AphiaID
from read_parquet('s3://obis-products/speciesgrids/h3_7/*')
where ST_Intersects(geometry, ST_GeomFromText('{wkt}'))
group by kingdom, phylum, class, family, genus, species, AphiaID
"))This data product is used in the speedy package which combines species distribution data with WoRMS distributions, thermal envelopes, and kernel densities. Speedy in turn is used for applications such as the Pacific islands Marine bioinvasions Alert Network (PacMAN).
Other data usage examples are available as notebooks.
The following source datasets need to be prepared:
- OBIS occurrence snapshot
- GBIF occurrence snapshot
- WoRMS export (taxon and species profile tables)
- IUCN Red List export
- GBIF taxonomic backbone to WoRMS taxonomy from ChecklistBank
Adapt the file paths and grid configuration in speciesgrids/__main__.py and run:
python -m speciesgridsaws s3 sync geohash_4 s3://obis-products/speciesgrids/geohash_4
aws s3 sync h3_7 s3://obis-products/speciesgrids/h3_7
The code in this repository is licensed under the MIT License.
The speciesgrids dataset on S3 is licensed under CC BY-NC 4.0, because the GBIF occurrence download it is built from is licensed CC BY-NC 4.0. A copy of the license and a README are stored alongside the data in s3://obis-products/speciesgrids/.
Funded by the European Union under the Horizon Europe Programme, Grant Agreement No. 101112823 (DTO-BioFlow). Views and opinions expressed are however those of the author(s) only and do not necessarily reflect those of the European Union or the European Research Executive Agency (REA). Neither the European Union nor the granting authority can be held responsible for them.