CDav
CDav

Reputation: 197

Add bathymetry lines to ggplot using marmap package and getNOAA.bathy

I am wanting to add bathymetry lines to a map plot I am looking at. I am plotting points off the coast and we are interested as to how close to the continental shelf they are. I have seen a package called Marmap - but now I am using ggplot as it gives a higher resolution.

The code I've seen for getting bathymetry lines is this:

library(marmap)

Peru.bath <- getNOAA.bathy (lon1 = -90, lon2 = -70, lat1 = -20, 
                            lat2 = -2, resolution = 10) 

plot(Peru.bath)

The code I'm using which I want to add the bathymetry lines to is below:

coast_map <- fortify(map("worldHires", fill=TRUE, plot=FALSE))
gg <- ggplot()
gg <- gg + geom_map(data=coast_map, map=coast_map,
                    aes(x=long, y=lat, map_id=region),
                    fill="white", color="black") +
  theme(panel.background = element_blank()) + 
  theme(panel.grid.major = element_blank()) + 
  theme(panel.grid.minor = element_blank()) +
  theme(axis.text.x = element_blank(), axis.text.y = element_blank(), axis.ticks = element_blank())
gg <- gg + xlab("") + ylab("")
gg <- gg + geom_map(data=data.frame(region="Peru"), map=coast_map,
                    aes(map_id=region), fill="gray") 
gg <- gg + xlim(-90,-70) + ylim(-20,-2)
gg <- gg + coord_map()
gg

Therefore I assumed it would be

gg <- gg + Peru.bath

However I am getting 'Error: Don't know how to add Peru.bath to a plot'

NB Just to make it clear, I do not have bathymetry data, I just wish to plot known shelf lines onto a map I have created, if that is possible.

Upvotes: 5

Views: 6340

Answers (3)

Benoit
Benoit

Reputation: 1234

I've just updated the development version of marmap on github. You can install it with:

library(devtools)
install_github("ericpante/marmap")

A function autoplot.bathy() for plotting bathy objects with ggplot2 is now included. Be sure to check it's help file and the examples to see what's possible. Here is an example with your dataset dat:

library(marmap) ; library(ggplot2)
dat <- getNOAA.bathy(-90,-70,-20,-2,res=4, keep=TRUE)

# Plot bathy object using custom ggplot2 functions
autoplot(dat, geom=c("r", "c"), colour="white", size=0.1) + scale_fill_etopo()

enter image description here

Upvotes: 10

Benoit
Benoit

Reputation: 1234

If you want to (i) add isobath lines to your map and (ii) determine the depth of your data points using get.depth() it would be much easier to stick with standard plots (marmap is designed to work with these). As a matter of fact, the "better resolution" you mention has nothing to do with base graphics nor ggplot2. In your example, the coastline you're plotting comes from the "worldHires" dataset from package mapdata and it has nothing to do with ggplot2. Indeed, you can add the same coastline on marmap plots.

Here is some code to produce two more than decent maps using base graphics and marmap:

library(marmap) ; library(mapdata)

# Get bathymetric data
dat <- getNOAA.bathy(-90,-70,-20,-2,res=4, keep=TRUE)

# Create nice color palettes
blues <- c("lightsteelblue4", "lightsteelblue3", "lightsteelblue2", "lightsteelblue1")
greys <- c(grey(0.6), grey(0.93), grey(0.99))

## First option for plotting
plot(dat, land=TRUE, n=100, lwd=0.03)
map("worldHires", res=0, add=TRUE)

# Second option
plot(dat, im=TRUE, land=TRUE, bpal=list(c(min(dat),0,blues),c(0,max(dat),greys)), lwd=.05, las=1 )
map("worldHires", res=0, lwd=0.7, add=TRUE)

# Add -200m and -1000m isobath
plot(dat, deep=-200, shallow=-200, step=0, lwd=0.5, drawlabel=TRUE, add=TRUE)
plot(dat, deep=-1000, shallow=-1000, step=0, lwd=0.3, drawlabel=TRUE, add=TRUE)

Note that the resolution used here is not the highest possible. the res argument of getNOAA.bathy() is set to 4 here. This downloads a 2.7Mb dataset that can be saved locally by setting the keep argument to TRUE. The highest resolution possible would be res=1, but in my opinion, it is overkill for such a wide geographical scale. This code produces the 2 plots below:

First option: wireframe plot Second option: image plot

Upvotes: 4

hrbrmstr
hrbrmstr

Reputation: 78792

Running a bit short on time this morning, but this should help you get started (and, can no doubt be improved by other R geo folks:

library(maps)
library(mapdata)
library(ggplot2)
library(marmap)
library(Grid2Polygons)

coast_map <- fortify(map("worldHires", fill = TRUE, plot = FALSE))

Peru.bath <- getNOAA.bathy (lon1 = -90, lon2 = -70, lat1 = -20,
                            lat2 = -2, resolution = 10)

peru_bathy_df <- Grid2Polygons(as.SpatialGridDataFrame(Peru.bath), 
                               level=TRUE, pretty=TRUE)
peru_bathy_map <- fortify(peru_bathy_df)

gg <- ggplot()
gg <- gg + geom_map(data=peru_bathy_map, map=peru_bathy_map,
                    aes(map_id=id), color="black", fill="white")
gg <- gg + geom_map(data=coast_map, map=coast_map,
                    aes(x=long, y=lat, map_id=region),
                    fill="white", color="black")
gg <- gg + geom_map(data=data.frame(region="Peru"), map=coast_map,
                    aes(map_id=region), fill="steelblue")
gg <- gg + xlim(-90,-70) + ylim(-20,-2)
gg <- gg + coord_map()
gg <- gg + theme_bw()
gg

enter image description here

Obviously you want a better picture than that, but the basic idea is to get it converted into an object that ggplot can handle (so, a SpatialPolygonsDataFrame). Lots of good non-ggplot examples in the bathy and Grid2Polygons help.

NOTE: these take some time to convert/render and the bathy examples do show a way to do this without ggplot that will be much faster.

Upvotes: 2

Related Questions