Map in ggplot2 visualization/displaying bug? - r

As you can see below, there is a weird displaying problem on the maps I made using ggplots. The same problem seems to happen with any projection.
Here is the code:
Only the packages maps and ggplot2 are needed
mapWorld <- borders("world", colour="gray50", fill="black")
ggplot() + mapWorld +
coord_map("mercator") +
ylim(-90,90)

Apparently the problem is caused by the polygons that cross the 0 coordinate, the place in which the world merges. R dont knows how to close those polygons and projects them all around the world.
This method recreates the polygons and prevents them from crossing the 0 coordinate (xlim and ylim). It works with any kind of projection.
require(ggplot2)
require(PBSmapping)
require(data.table)
mapWorld <- map_data("world")
setnames(mapWorld, c("X","Y","PID","POS","region","subregion"))
worldmap = clipPolys(mapWorld, xlim=xlim,ylim=ylim, keepExtra=TRUE)
ggplot() + geom_polygon(data = mapWorld, aes(X,Y,group=PID))

why you need to use?
ggplot() + mapWorld +
coord_map("mercator") +
ylim(-90,90)
if u use just
ggplot() + mapWorld
It works perfectly

Related

plot GPS position over the road

How can I plot GPS trajectory over road and zoom on that road?
Can someone please take a point (40.74640013950355, -73.98755303328286, in Manhattan) and plot it over the corresponding road network [may be a grid 600ft by 600ft]. Please edit the code below to illustrate -
lat <- 40.74640013950355
long <- -73.98755303328286
tbl <- tibble(lat, long)
ggplot(data = tbl,
aes(x = lat,
y = long)) +
geom_point()
Once I know how to plot the road and I can overlay my trajectory data by modifying tbl above.
Thanks
There is no big difficulty to achieve such plot, starting from the example given in tigris library:
library(tigris)
library(ggplot2)
library(ggthemes)
roads <- roads("Maine", "031")
gg <- ggplot() + geom_sf(data = roads, color="black", fill="white", size=0.25) + theme_map()
lat <- 43.5; long <- -70.6; bbox = 0.02
bbox_gg = coord_sf(xlim=c(long-bbox/2, long+bbox/2), ylim=c(lat-bbox/2, lat+bbox/2))
gg + geom_point(data=data.frame(lat, long), aes(x=long, y=lat), size=4, color="red") + bbox_gg
What is done here is just adding a geom_point() aesthetic on top of the geom_sf() layer. We can use a kind of bounding box coordinate limit to adjust the zoom
EDIT
If you need some road names on your map, you can add this to the plot:
geom_sf_label(data=subset(roads, roads$RTTYP!="M"), aes(label=FULLNAME))
here I use subset to avoid plotting all little road names. Eventually, you might want to find a way to zoom/subset your data before plotting, because it's gonna be too long to do it like this.

R coord_map versus coord_proj proj4 with ortho projection

In an attempt to reproduce
https://en.wikipedia.org/wiki/Central_African_Republic#/media/File:Central_African_Republic_-_Location_Map_(2013)_-CAF-_UNOCHA.svg
My first challenge is to reproduce the orthogonal projection without artifacts:
library(rworldmap)
library(ggplot2)
library(ggalt)
map.world <- map_data(map="world")
gg <- ggplot() +
geom_cartogram(aes(long, lat, map_id = region), data=map.world, map=map.world)
gg + coord_map("ortho", orientation = c(4.22, 18.35, 0))+theme_map()
coord_map returns some artifacts in the shapefiles near the edge of the sphere (e.g. China. (straight lines instead of arcs)
Can this be solved by using proj4, coord_proj?
Is there a way to give the globe/oceans a background colour?

R - plotly - ggplot

I found the following example for plotting a map with Canadian cities: https://plot.ly/ggplot2/maps/
The R code reads as follows:
library(plotly)
Sys.setenv("plotly_username"="XXXXXXXXX")
Sys.setenv("plotly_api_key"="YYYYYYYYY")
data(canada.cities, package="maps")
viz <- ggplot(canada.cities, aes(long, lat)) +
borders(regions="canada", name="borders") +
coord_equal() +
geom_point(aes(text=name, size=pop), colour="red", alpha=1/2, name="cities")
ggplotly()
I would like to modify the example in a way that the name of the city shows up when hovering with the mouse over the relevant point in the map.
How would I need to modify the above example to implement this?
This ended up being a bug, so thanks for reporting! I just issued a fix here so try re-installing (devtools::install_github("ropensci/plotly")) and re-running:
data(canada.cities, package="maps")
viz <- ggplot(canada.cities, aes(long, lat)) +
borders(regions="canada", name="borders") +
coord_equal() +
geom_point(aes(text=name, size=pop), colour="red", alpha=1/2, name="cities")
ggplotly()
Here's a screenshot, with the custom hover text!

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.
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()
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:
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
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.

Fix antarctica on a ggplot world map?

I want to plot a simple world map with gpplot, but when I do, antarctica gets cut off, because the coordinates don't wrap around, so the path goes back across the whole map, instead of going out the edges. For example:
world_data <- map_data("world")
ggplot() + scale_y_continuous(limits=c(-90,90), expand=c(0,0)) +
scale_x_continuous(expand=c(0,0)) +
theme(axis.ticks=element_blank(), axis.title=element_blank(),
axis.text=element_blank()) +
geom_polygon(data=world_data, mapping=aes(x=long, y=lat, group=group), fill='grey')
Produces:
But the sounthern most part of antarctica is missing - it should look like this:
Is there a simple way to fix this problem?
The wrld_simpl data file from the maptools package seems to have more reliable map data, including data for Antarctica that goes all the way to -90 degrees latitude. For example:
library(maptools)
data(wrld_simpl)
ggplot() +
geom_polygon(data=wrld_simpl,
aes(x=long, y=lat, group=group), fill='grey20') +
coord_cartesian(xlim=c(-180,180), ylim=c(-90,90)) +
scale_x_continuous(breaks=seq(-180,180,20)) +
scale_y_continuous(breaks=seq(-90,90,10))
Hi #eipi10: your code does not work well when setting coord_map(). Antarctica looks weird.
ggplot() +
geom_polygon(data=fortify(wrld_simpl),
aes(x=long, y=lat, group=group), fill='grey20') +
coord_map(xlim=c(-180, 180), ylim=c(-90, 90)) +
scale_x_continuous(breaks=seq(-180, 180, 20)) +
scale_y_continuous(breaks=seq(-90, 90, 10))
Actually I found that most built-in world maps in R packages such as mapdata, maptools and maps don't work correctly with coord_map(). Highly appreciate it if someone can figure it out.

Resources