在ggplot2中转换rworldmap

时间:2015-01-12 10:59:16

标签: r ggplot2 rworldmap

我在ggplot中有一张地图(由geom_polygon,lines,points和segments组成)。原版是在WGS中,所有单位都是纬度/经度。所有附加数据(线和点)也都是度数。我想将整个事物转换成等面积投影(Mollweide)。第一步(转换底层的rworldmap多边形)是相当轻松的,虽然有一些奇怪的水平线贯穿。但是,我不确定如何解决下一步。正如我所说的,所有数据都以度为单位,我想以度为单位指定xlim / ylim,轴标签和(曲线)网格线。我是否必须将所有内容转换为Mollweide米,或者是否可以在一个无痛的步骤中重塑我的最终地图对象?

这是我到目前为止所展示的这些奇怪的水平线。

library(rworldmap)
library(rgdal)
library(ggplot2)

moll_crs<-CRS("+proj=moll +R=10567000 +lon_0=0 +x_0=0 +y_0=0 +units=m +towgs84=0,0,0,0,0,0,0 +no_defs")

ggplot() + 
  geom_polygon(data = spTransform(getMap(resolution = 'low'), CRSobj = moll_crs), 
               aes(x = long, 
                   y = lat, 
                   group = group),
               fill = 'gray90', 
               colour = 'gray10', 
               size = 0.3) +
  coord_fixed()

这导致水平线。

enter image description here

编辑:

按照@hrbmstr的回答,我正在使用他的GeoJSON文件coord_map("molleweide")

ggplot() + 
  geom_map(data=world, map=world,
           aes(x=long, y=lat, map_id=id), 
           fill="gray90", color="gray10", size=0.3) +
  coord_map("mollweide",
            xlim = c(-50, 40))

虽然xlim参数搞砸了,但却添加了水平线。我认为coord_***(xlim)参数只是改变了可视区域,但它似乎影响了地图的绘制方式。有任何想法吗? enter image description here

2 个答案:

答案 0 :(得分:3)

你可以让ggplot为你做,你也可以通过使用更好的地图摆脱线条。我在下面引用的GeoJSON文件是从Natural Earth shapefile创建的,你可以从那里使用shapefile(或者我从here制作的优化GeoJSON)。

为了展示它如何处理额外的点,我为USA&amp;添加了近似质心。 AUS

library(sp)
library(ggplot2)
library(rgdal)
library(rgeos)

world <- readOGR("ne_50m_admin_0_countries.geojson", "OGRGeoJSON")
outline <- bbox(world)
outline <- data.frame(xmin=outline["x","min"],
                      xmax=outline["x","max"],
                      ymin=outline["y","min"],
                      ymax=outline["y","max"])

world <- fortify(world)

points <- data.frame(lon=c(-98.35, 134.21), lat=c(39.5, -25.36))

gg <- ggplot()
gg <- gg + geom_rect(data=outline, 
                     aes(xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax), 
                     color=1, fill="white", size=0.3)
gg <- gg + geom_map(data=world, map=world,
                    aes(x=long, y=lat, map_id=id), 
                    fill="gray90", color="gray10", size=0.3)
gg <- gg + geom_point(data=points, aes(x=lon, y=lat), size=3)
gg <- gg + labs(x=NULL, y=NULL)
gg <- gg + coord_map("mollweide")
gg <- gg + theme_bw()
gg <- gg + theme(panel.grid=element_blank())
gg <- gg + theme(panel.border=element_blank())
gg <- gg + theme(axis.ticks=element_blank())
gg <- gg + theme(axis.text=element_blank())
gg


gg

enter image description here

您可以提前剪辑世界,以避免coord_map

出现问题
world <- readOGR("ne_50m_admin_0_countries.geojson", "OGRGeoJSON")
clipper <- as(extent(-50, 40, -60, 60), "SpatialPolygons")
proj4string(clipper) <- CRS(proj4string(world))

world <- gIntersection(world, clipper, byid=TRUE)
world <- fortify(world)

gg <- ggplot()
gg <- gg + geom_map(data=world, map=world,
                    aes(x=long, y=lat, map_id=id), 
                    fill="gray90", color="gray10", size=0.3)
gg <- gg + labs(x=NULL, y=NULL)
gg <- gg + coord_map("mollweide")
gg

(注意:我没有包含上面的所有代码以避免混乱)。您也可以使用相同的边界框代码在剪裁的地图周围放置投影边框。

enter image description here

答案 1 :(得分:1)

从rworldmap地图中排除antarctica是纠正恼人水平线的一种方法。另请注意,您只需要从resolution中的默认值rworldmap::getMap()获得的粗分辨率地图。

以下是对问题第一部分的解决方案,只需对代码进行最少的更改。

moll_crs<-CRS("+proj=moll +ellps=WGS84")
#first get countries excluding Antarctica which can crash spTransform
#for a world plot you only need coarse resolution which is the default for getMap()
sPDF <- getMap()[getMap()$ADMIN!='Antarctica',]

ggplot() + 
  geom_polygon(data = spTransform(sPDF, CRSobj = moll_crs), 
               aes(x = long, 
                   y = lat, 
                   group = group),
               fill = 'gray90', 
               colour = 'gray10', 
               size = 0.3) +
  coord_fixed()