The ggOceanMaps package for R allows plotting data on bathymetric maps using ggplot2. The package is designed for ocean sciences and greatly simplifies bathymetric map plotting anywhere around the globe. ggOceanMaps uses openly available geographic data. Citing the particular data sources is advised by the CC-BY licenses whenever maps from the package are published (see the Citations and data sources section). Note that the package comes with absolutely no warranty and that maps generated by the package are meant for plotting scientific data only. The maps are coarse generalizations of third party data and therefore inaccurate.
ggOceanMaps extends on ggplot2. Data that contain geographic information can be plotted on the maps generated by ggOceanMaps using the ggplot2 layers separated by the
+ operator. The package uses spatial shapefiles, GIS packages for R to manipulate, and the ggspatial package to help to plot these shapefiles. The shapefile plotting is conducted internally in the
basemap function and uses ggplot’s sf object plotting capabilities.
The primary aim of ggOceanMaps is to make plotting oceanographic spatial data as simple as feasible, but also flexible for custom modifications. The “as simple as feasible” part will be covered in this section, while the “flexible for custom modifications” part is covered in the Advanced use section. The basic use section of this tutorial assumes that the user knows how to use ggplot. If you are not familiar with this package, you may read the Data visualization section in Hadley Wickham & Garrett Grolemund. This tutorial does not describe functions in ggOceanMaps but rather focusses on how to use them. Make sure to refer to the function documentation while reading the tutorial. The package requires the
ggOceanMapsData package which is not available on CRAN but should be installed automatically when you load
ggOceanMaps for the first time. If the automatic installation does not work, please use:
Once the packages have been installed, you can load them normally:
To ensure simplicity, ggOceanMaps package attempts to use decimal degree coordinate system as much as possible. This system represents coordinates on a sphere, while maps are plotted in two dimensions. Therefore, the underlying map data have to be projected using different mathematical algorithms depending on the geographic location. The simplest way of defining the geographic location is to use the
limits argument with decimal degrees. The limits argument can be defined either as a numeric vector of length 1 or 4. Specifying the argument as a single integer between 30 and 88 or -88 and -30 plots a polar stereographic map for the Arctic or Antarctic, respectively.
Rectangular maps are plotted by specifying the
limits argument as a numeric vector of length 4 where the first element defines the start longitude, the second element the end longitude, the third element the minimum latitude and the fourth element the maximum latitude of the bounding box:
Limiting maps using decimal degrees is somewhat counter-intuitive because maps plotted for polar regions (>= 60 or <= -60 latitude) are actually projected to Arctic and Antarctic polar stereographic systems. Because decimal degrees are angular units running counter-clockwise, also the longitude limits have to be defined counter-clockwise. Projected maps with decimal degree
limits will lead to expanded limits towards the poles when using Arctic and Atlantic Polar Stereographic projections because decimal degrees represent a sphere:
The figure above: Limiting rectangular basemaps is done by placing four coordinates to the limit argument. A) If the limits are in decimal degrees, the longitude limits (
[1:2]) specify the start and end segments of corresponding angular lines that should reside inside the map area. The longitude limits are defined counter-clockwise. The latitude limits
[3:4] define the parallels that should reside inside the limited region given the longitude segments. Note that the resulting limited region (polygon with thick red borders) becomes wider than the polygon defined by the coordinates (thin red borders). The example limits are
c(120, -120, 60, 80). B) If the limits are given as projected coordinates or as decimal degrees for maps with |latitude| < 60, limits elements represent lines encompassing the map area in cartesian space. The example limits are the limits from A) projected to the Arctic stereographic (crs = 3995). When limiting basemaps using data, the limits are calculated for the maximum reach of projected coordinates as in B but with an added buffer to place all points inside the map area.
As an example:
Exact control of map limits can be difficult using decimal degree limits in polar regions. The
limits argument also allows specifying the limits in the underlying projected coordinate units. First, we will need to find out how these units look like:
projection.grid argument plots a grid using the projected actual map coordinates instead of decimal degrees. The grid helps in defining the
limits using projected coordinates giving better control over the map limits than decimal degree coordinates. The automatic shapefile definition algorithm does not work for projected coordinates. Therefore, if the limits are not given as decimal degrees (any longitude outside the range [-180, 180] or latitude [-90, 90]), the function asks to specify
shapefiles can be defined by partially matching the names of the pre-made shapefiles in
shapefile_list (e.g. “Ar” would be enough for “ArcticStereographic”):
The limits of a map can also be defined by inputting a data frame to the
data argument. The limits are automatically defined allowing the user to quickly find limits for a desired spatial dataset:
Note how the function expands the map to make all data fit inside the map area compared to a similar plot using the
limits argument above. The function automatically detects columns containing longitude and latitude information. The automatic detection algorithm is not very advanced and it is recommended to use intuitive column names for longitude (such as “lon”, “long”, or “longitude”) and latitude (“lat”, “latitude”) columns. The coordinate data have to be given as decimal degrees for the
data argument to function.
It is advised to limit your map first and only then plot bathymetry and glaciers to save the processing time of your computer (the bathymetry shapes can be large). Bathymetry is plotted simply by specifying
bathymetry = TRUE:
Glaciers can be plotted using the
basemap(...) function works almost similarly to the
ggplot(...) function as a base for adding further layers to the plot. The difference between the
basemap() and the
ggplot() is that the
basemap() plot already contains multiple ggplot layers. All layers except bathymetry have no other
aes mapping than
group. Bathymetry is mapped to
color color in addition. This means that when you add ggplot layers, you need to specify the
data argument explicitly as shown below. Another difference is that basemaps are plotted using projected coordinates. The ggspatial and ggplot’s
geom_sf functions convert the coordinates automatically to the projected coordinates:
The ggplot functions can also be used, but the coordinates need to be transformed to the basemap projection first using the
Note that the maps plotted in temperate and tropical regions are not projected. Consequently, decimal degrees work for such maps directly:
transform_coord function detects the projection automatically, given that the map is limited using a similar range of coordinates. Therefore you can use the
transform_coord as demonstrated above whenever using standard ggplot layers.
The stereographic maps can be rotated to point towards north using the
A word of warning, however: the rotation involves reprojecting all shapefiles in their entirety and is memory consuming especially for large bathymetry shapes. Make sure to limit your map correctly before you add bathymetry. The rotation is still experimental and does not work for
limits defined using projected coordinates or
data. This functionality is likely to contain a whole lot of bugs. Rotation does not currently work within the
transform_coord() function. Use the
ggspatial::geom_spatial_* functions when adding data to rotated maps.
qmap function is designed as a shortcut to quickly take a look at a spatial dataset similar to the ggplot’s
qplot function. This function is supposed to automatically detect the type of data fed into the function and plot a map using appropriate geometries, limits, and projection. The function has not been developed properly yet and requires user feedback and testing.
This section focuses on flexibility and user modifications. It is assumed that advanced users understand the basics of geographic information systems (GIS) and how to use these systems in R (e.g. see the Making Maps with R chapter in Lovelace et al. 2020).
basemap function uses the
limits argument to automatically detect the required projection for a map (or the
data argument to calculate
limits). The algorithms deciding which projection to use are defined in
shapefile_list functions. These conditions are expected to change during the development of the package and documented information here or in the
basemap function might be outdated. Make sure to check the projection definition functions for up-to-date information. At the time of writing, the function uses three different projections (given as EPSG codes):
limits) >= 60 (if min latitude (
limits) >= 30), and single integer latitudes >= 30 and <= 89.
limits) <= -60 (if min latitude (
limits) <= -30), and single integer latitudes <= -30 and >= -89.
limits) < 30 or > -30, max latitude (
limits) < 60 or > -60, and single integer latitudes < 30 and > -30.
basemap function uses pre-transformed shapefiles for each of the projections above (defined in
shapefile_list). This is to make the plotting quicker and more memory efficient but leads to larger data size required by the package.
basemap function contains four pre-made bathymetry styles defined using the
bathy.style argument. Two of these alternatives (
"poly_*") have been mapped to
fill using the
geom_polygon function, while the two others (
contour_*) have been mapped to
color. The default style (
"poly_blues") has been displayed throughout this user manual. The other styles are:
bathy.style = "poly_*" bathymetry polygons are mapped to
geom_fill_discrete and can be modifying using standard ggplot syntax:
bathy.style = "contour_*" bathymetry lines are mapped to
geom_color_discrete and can be modifying using standard ggplot syntax:
basemap function uses graphical parameters that (very objectively) happen to please the eye of the author and have worked in the applications needed by the author. The default parameters may suddenly change without warning. You may want to modify the appearances of a
basemap to your own liking. This can be done using the
*.border.col (line color) and
*.size (line width) arguments:
Grid lines can be removed by setting the
NA. Axis labels can be manipulated using standard ggplot code: