1

我在 ggplot 中有一张地图(由 geom_polygon、线条、点和线段组成)。原件在 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()

这导致水平线。

在此处输入图像描述

编辑:

在@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)参数只是改变了可视区域,但它似乎影响了地图的绘制方式。有任何想法吗? 在此处输入图像描述

4

2 回答 2

3

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

为了展示它如何处理附加点,我为美国和澳大利亚添加了闭合质心

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

在此处输入图像描述

您可以提前剪辑世界以避免出现以下问题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

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

在此处输入图像描述

于 2015-01-12T12:04:51.543 回答
1

从 rworldmap 地图中排除南极洲是纠正恼人水平线的一种方法。另外请注意,您只需要从 in 的默认值获得的粗分辨率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()
于 2015-01-12T13:01:13.007 回答