问题
I'm trying to plot with ggplot2 the track of a bird around the antarctic. So far I have a map projected in polar coordinates, I also managed to plot the track points correctly and I almost link them correctly but...
As the track crosses the international date line (i.e. longitude 180°) ggplot2 is not able to correctly link the 2 points in either sides of the line. It does connect them but by going all the way around the earth. So I'm looking for a way to force ggplot to link the points by the shortest road across the 180°.
Here is my code and the resulting graph.
require(ggplot2)
require(rgdal)
data:
track<-read.table("NOGP_87470_track.txt", sep="\t",h=T)
consists of 75 track points characterized by longitude / latitude / date (POSIXct). PTT is the name of the bird. Date is of no use here.
head(track)
:
PTT long lat date
1 87470 51.645 -46.334 2009-02-03 14:50:00
2 87470 52.000 -46.289 2009-02-04 20:11:00
3 87470 52.556 -46.083 2009-02-06 07:15:00
4 87470 55.822 -44.667 2009-02-07 17:28:00
5 87470 60.679 -41.915 2009-02-09 04:03:00
6 87470 63.059 -41.649 2009-02-10 15:04:00
Here is the part of the data where track cross the line (line: 19 & 20)
PTT long lat date
18 87470 160.907 -53.356 2009-02-28 06:25:00
19 87470 165.791 -54.588 2009-03-01 15:39:00
20 87470 -174.636 -50.893 2009-03-03 05:04:00
21 87470 -160.111 -50.832 2009-03-04 13:47:00
22 87470 -138.875 -53.474 2009-03-06 01:49:00
map (shapefile of the world coastlines in cartesian coordinates)
world<-readOGR("Coastlines\\World_continental_WGS84_Proj.shp", "World_continental_WGS84_Proj")
plot
p <- ggplot(track, aes(x=long, y=lat))
p <- p + geom_polygon( data=world, aes(x=long, y=lat, group = group),colour="grey", fill="gainsboro" ) +
theme( panel.grid.major.x = element_blank()) +
coord_polar(theta="x", start=pi/2,direction=1) + # project the map in polar coordinates
ylim (-90, -20) # to keep only south hemisphere
pp <- p + geom_point(size=3,shape=19) + geom_path(size=1,col="grey")
And here is what I get:
red arrows are the flight direction of the bird:
I colored in green the 2 points I want to link accross the 180° line and manually made a green dotted line between them. As you can see they are connected by a line which goes all around the pole in the wrong direction.
Does anyone got an idea on how do deal with that?
回答1:
You can achieve this by using coord_map rather than coord_polar, and ensuring that the longitudes don't wrap round to -180 degrees but rather continue to increase. I don't have access to your original data nor the map you're using, so I've produced my own dummy dataset.
Load packages and create map and track data:
library("ggplot2")
library("dplyr")
south_map <- map_data("world") %>% group_by(group) %>% filter(min(lat) <= -20)
track <- data.frame(long = cumsum(c(210, rnorm(100, 5, 2))) %% 360 - 180,
lat = cumsum(c(-50, rnorm(100, 0.1, 2))))
Initial polar plot
ggplot(track, aes(x=long, y=lat)) +
geom_polygon(aes(group = group), data = south_map, colour = "grey", fill = "gainsboro") +
theme(panel.grid.major.x = element_blank()) +
coord_polar(theta="x") + # project the map in polar coordinates
ylim(-90, -20) + # to keep only south hemisphere
geom_point(size = 3, shape = 19, colour = "red") + geom_path(size = 1, colour = "grey")
Fix longitudes so that they keep increasing
track_new <- track
long_diff <- diff(track$long)
long_diff[long_diff < -180] <- long_diff[long_diff < -180] + 360
track_new$long <- cumsum(c(track$long[1], long_diff))
Plot using map projection
ggplot(track_new, aes(x = long, y = -lat)) +
geom_polygon(aes(group = group), data = south_map, colour = "grey", fill = "gainsboro") +
coord_map("azequidistant") +
geom_point(size = 3, shape = 19, colour = "red") +
geom_path(size = 1, col = "grey") +
scale_x_continuous(breaks = NULL) +
scale_y_continuous("latitude", breaks = 25 * 0:3, labels = -25 * 0:3)
I'm not sure if it's possible to centre an azequidistant projection on the South Pole so I've taken the negative of the latitude and sorted this out in the labelling stage. I've also removed the x scale since it currently doesn't really work for coord_map as far as I can tell. You could use geom_text
to manually add some markers in if needed.
来源:https://stackoverflow.com/questions/25157221/how-to-link-correctly-track-points-around-a-polar-projection-map