How to link correctly track points around a polar projection map?

半世苍凉 提交于 2019-12-19 03:59:27

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!