在 ggplot2 中转换 rworldmap
transform rworldmap in ggplot2
我在 ggplot 中有一张地图(由 geom_polygon、线、点和线段组成)。原件在 WGS 中,所有单位都是度 lat/lon。所有附加数据(线和点)也以度为单位。我想将整个事物重新转换为 equal-area 投影 (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)
参数只是改变了可视区域,但它似乎影响了地图的绘制方式。有任何想法吗?
你可以让ggplot为你做,你也可以通过使用更好的地图来摆脱线条。我在下面引用的 GeoJSON 文件是从 Natural Earth shapefiles and you can just use the shapefile from there (or the optimized GeoJSON I made from here) 创建的。
为了展示它如何处理额外的点,我为美国和澳大利亚添加了接近质心
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
(注意:为了避免混乱,我没有包含上面的所有代码)。您也可以使用相同的边界框代码在裁剪地图周围放置投影边框。
从 rworldmap 地图中排除南极洲是纠正烦人的水平线的一种方法。另外请注意,您只需要从 rworldmap::getMap()
中的默认值 resolution
获得的粗分辨率贴图。
这里是您问题第一部分的解决方案,只需对您的代码进行最少的更改。
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()
我在 ggplot 中有一张地图(由 geom_polygon、线、点和线段组成)。原件在 WGS 中,所有单位都是度 lat/lon。所有附加数据(线和点)也以度为单位。我想将整个事物重新转换为 equal-area 投影 (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)
参数只是改变了可视区域,但它似乎影响了地图的绘制方式。有任何想法吗?
你可以让ggplot为你做,你也可以通过使用更好的地图来摆脱线条。我在下面引用的 GeoJSON 文件是从 Natural Earth shapefiles and you can just use the shapefile from there (or the optimized GeoJSON I made from here) 创建的。
为了展示它如何处理额外的点,我为美国和澳大利亚添加了接近质心
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
(注意:为了避免混乱,我没有包含上面的所有代码)。您也可以使用相同的边界框代码在裁剪地图周围放置投影边框。
从 rworldmap 地图中排除南极洲是纠正烦人的水平线的一种方法。另外请注意,您只需要从 rworldmap::getMap()
中的默认值 resolution
获得的粗分辨率贴图。
这里是您问题第一部分的解决方案,只需对您的代码进行最少的更改。
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()