Introduction
Mapping the western Indian Ocean region with bathymetry and country labels can provide valuable insights into the geographical and topographical features of the area. Using R, we can achieve this by leveraging powerful libraries such as ggplot2, sf, rnaturalearth, and marmap. This allows for the creation of detailed maps that showcase the underwater terrain, coastlines, and political boundaries of the region, enabling a deeper understanding of its physical geography.
First, we need to load the required packages. These packages will provide the necessary functions and datasets to create our map. If the packages are not installed, please install them first before loading them in the session
Define Map Extent
Then we define the geographic extent of a map by specifying the minimum and maximum longitudes and latitudes. This step is important for focusing the map specifically on the western Indian Ocean region. By setting these boundaries, the map will display only the area within the specified coordinates, allowing for a targeted visualization of the desired region.
Get Bathymetry Data
We then use he getNOAA.bathy
function from the marmap package (Pante et al., 2023) to retrieve bathymetry data (underwater topography) for the region, and the resolution parameter sets the resolution of the data.
Convert Bathymetry Data to Data Frame
The bathymetry data obtained from the NOAA dataset is in matrix form. To plot it with ggplot2 package (Wickham, 2016), we need to convert it to a data frame or raster. This makes it easier to work with in the context of plotting functions.
Get World Map Data and Crop to Extent
We retrieve world map data using the ne_countries
function from the rnaturalearth package (Massicotte and South, 2023). This function returns spatial data for world countries.
We then crop this data to the desired map extent using the st_crop
function from the sf package (Pebesma, 2018).
Then we filter the countries that are within the Western Indian Ocean region. We use filter
function from dplyr package (Wickham et al., 2019) to pick ten countries in the region.
Create a labels and description
Then we create a tibble derived from the simple feature that contains coordinates (latitude and longitude) and description of population and economy for each country in the region
wio.tb = wio.sf |>
st_centroid() |>
st_coordinates() |>
as_tibble() |>
select(lon = 1, lat = 2) |>
bind_cols(
wio.sf |>
st_drop_geometry() |>
separate(economy, into = c("a", "economy"), sep = 2) |>
separate(income_grp, into = c("a", "income_grp"), sep = 2) |>
select(-a) |>
mutate(
name = str_to_upper(name),
description = paste0(
"Population: ", scales::number(pop, big.mark = ","),"\n",
"Income group: ", income_grp
)
)
)
Plot the Map with Bathymetry
We use ggplot2 to generate the map. The geom_raster function is employed to plot the bathymetry data, employing a color gradient to represent varying depth. The geom_sf
function is used to plot the country boundaries, and the coord_sf
function ensures the map is plotted within the defined geographic extent. The geom_mark_circle
function from ggforce package (Pedersen, 2024) is then used to add these labels to the map. This enhances the map by providing clear, readable labels for key countries in the region.
ggplot() +
geom_spatraster(data = bathy.rast) +
geom_spatraster_contour(data = bathy.rast, breaks = -600) +
ggspatial::layer_spatial(data = world_cropped, fill = "grey70", color = "white") +
ggspatial::layer_spatial(data = wio.sf, fill = "palegreen4", color = "white") +
ggforce::geom_mark_circle(
data = wio.tb,
aes(x = lon, y = lat, label = name, group = name, description = description),
show.legend=F, fill = "white",
alpha=0.8,
label.fontsize = 9,
label.fill = "grey85",
position = "jitter",
con.type = "elbow",
label.buffer = unit(8, "mm"),
expand = unit(2.5, "mm"),
con.cap = unit(.8, "mm"),
con.size = unit(.5, "mm"),
con.colour = "black")+
geom_point(data = wio.tb, aes(x = lon, y = lat), size = 2) +
ggspatial::annotation_scale(location = "bl")+
ggspatial::annotation_north_arrow(
location = "tr", width = unit(6, "mm"), height = unit(6, "mm")) +
coord_sf(xlim = c(25,65), ylim = c(-35,15))+
scale_fill_gradientn(
name = "Depth (m)",
colours=c("#5e24d6","#22496d","#042f66","#054780","#1074a6",
"#218eb7","#48b5d2","#72d0e1","#9ddee7","#c6edec"),
breaks=seq(0,-7000,-1000),
labels=seq(0,7000,1000),
trans = scales::modulus_trans(p = .6),
na.value = NA)+
theme_bw(base_size = 10)+
theme(
panel.background = element_blank(), # bg of the panel
panel.grid.major = element_line(linetype = "dotted", colour="grey30",linewidth=0.15),
panel.ontop = TRUE,
panel.grid.minor = element_blank(),
panel.border = element_rect(colour = "black", fill=NA, linewidth=1),
axis.title = element_blank(),
legend.position = c(0.90,.18)
)
Conclusion
This map offers valuable geographical and topographical insights, making it useful for various applications in research, education, and more. Adjust the coordinates and resolution as needed for more detailed or broader plotting, and feel free to customize the map further to suit your specific needs. By following these steps, you can create any detailed map of interest that includes both seafloor depth and country labels.
References
Citation
@online{semba2024,
author = {Semba, Masumbuko},
title = {Mapped: The Bathymetry of {WIO-Region}},
date = {2024-07-24},
url = {https://lugoga.github.io/kitaa/posts/mapping_wio/},
langid = {en}
}