Getting marine polygon maps in R

[This article was first published on modTools, and kindly contributed to R-bloggers]. (You can report issue about the content on this page here)
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Another frequent question of my students is how to obtain a polygon map of the seas and oceans, rather than the land polygons (countries, etc.) that are commonly imported with R spatial data packages. You can mostly just use the land polygons and do the opposite operation as you would do for terrestrial features — e.g., to colour the sea in a map of land polygons, just use the background instead of the col argument; to mask a raster map to the sea, just use the land polygons for a terra::mask() with inverse=TRUE; to select or crop features that overlap the sea, just do instead terra::erase() with the land polygons. But anyway, you may just prefer or need to have a marine polygon.

There are marine polygon maps available for download, e.g. at But if you don’t need the separation into particular seas or oceans or EEZs, you can easily create a global marine polygon from a countries map in R:

# import a world countries map:
countries <- geodata::world(path = tempdir())
terra::plot(countries, col = "tan")

# make a polygon map delimiting the entire extent of the Earth:
earth <- terra::vect(terra::ext(), crs = "EPSG:4326")
terra::plot(earth, col = "lightblue")
terra::plot(countries, col = "tan", add = TRUE)

# erase the countries (land parts) to get just the marine polygon:
marine <- terra::erase(earth, countries)
terra::plot(marine, col = "lightblue")

That’s it! See also terra::symdif(), or terra::mask(inverse=TRUE). You can then crop the marine polygon with your own other polygon or desired extent, e.g. terra::crop(marine, terra::ext(-20, 60, -40, 40)); and/or you can use the marine polygon to crop/mask other maps to the marine regions, e.g.:

# import a global bathymetry map:
bathy_source <- "/vsicurl/" # from
bathy <- terra::rast(bathy_source)
# terra::plot(bathy)  # slow

# crop bathymetry to a given extent:
bathy_crop <- terra::crop(bathy, terra::ext(110, 180, -50, 0))
terra::plot(bathy_crop, main = "Pixel values everywhere")
terra::plot(countries, add = TRUE)

# crop and mask bathymetry to keep values only on the marine polygon:
bathy_marine <- terra::crop(bathy_crop, marine, mask = TRUE)
terra::plot(bathy_marine, main = "Marine pixel values only")

See also this previous post for how to further crop/mask to the near-shore raster values, including for particular continents or islands.

To leave a comment for the author, please follow the link and comment on their blog: modTools. offers daily e-mail updates about R news and tutorials about learning R and many other topics. Click here if you're looking to post or find an R/data-science job.
Want to share your content on R-bloggers? click here if you have a blog, or here if you don't.

Never miss an update!
Subscribe to R-bloggers to receive
e-mails with the latest R posts.
(You will not see this message again.)

Click here to close (This popup will not appear again)