2016-08-16 120 views
2

我正在嘗試使用ggplot2在Winkel Tripel投影中繪製世界地圖;它最終會有一些數據。本質上,據我所知,ggplot不能做Winkel Tripel,所以我用手工投影來解決這個問題。除了海洋層之外,我已經擁有了一切,但沒有出現。代碼:geom_polygon +地圖投影=莫名其妙地切成兩個形狀?

suppressPackageStartupMessages({ 
    library(ggplot2) 
    library(sp) 
    library(rworldmap) 
    library(rgdal) 
}) 
ll.to.wt <- function (points) 
    as.data.frame(spTransform(SpatialPoints(points, CRS("+proj=longlat")), 
           CRS("+proj=wintri"))) 

world <- fortify(spTransform(getMap(), CRS("+proj=wintri"))) 
xlimits <- ll.to.wt(matrix(c(-180,180,0,0), nrow=2))$coords.x1 
ylimits <- ll.to.wt(matrix(c(0,0,-60,85), nrow=2))$coords.x2 
lseq = seq(-60, 85, by=.25) 
boundary <- ll.to.wt(data.frame(
    long = c(rep(-180, length(lseq)), rep(180, length(lseq)), -180), 
    lat = c(lseq,     rev(lseq),   lseq[1]))) 

ggplot() + 
    geom_polygon(data=boundary, aes(x=long, y=lat), fill="#9AC5E3") + 
    geom_map(data=world, map=world, aes(x=long, y=lat, map_id=id), 
      color="#888888", fill="#f2caae", size=0.25) + 
    scale_x_continuous(limits=xlimits, expand=c(0,0)) + 
    scale_y_continuous(limits=ylimits, expand=c(0,0)) + 
    coord_equal() + 
    theme(
     axis.line=element_blank(), 
     axis.text.x=element_blank(), 
     axis.text.y=element_blank(), 
     axis.ticks=element_blank(), 
     axis.title.x=element_blank(), 
     axis.title.y=element_blank(), 
     legend.justification = c(0,0), # bottom of box 
     legend.position  = c(0,0), # bottom of picture 
     panel.background=element_blank(), 
     panel.border=element_blank(), 
     panel.grid.major=element_blank(), 
     panel.grid.minor=element_blank(), 
     panel.margin=unit(0, "lines"), 
     plot.background=element_blank()) 

渲染:

world map drawn correctly except that the blue ocean fill only covers the "end caps" of the map, not the region in the middle

你可以看到什麼本來是一個多邊形填充已切碎成兩個單獨的多邊形,而且只涵蓋了「端蓋」的地圖,而不是中間的。我如何使它填充整個地圖?我認爲問題在於「邊界」的定義,但我沒有看到geom_polygon文檔中的任何內容來解釋什麼可能是錯誤的。

+0

我認爲這可能是一個領結多邊形,即LL,UL,LR,UR,LL而不是圍繞LL,UL,UR,LR,LL當這些代表上/下,左右一條合適的路徑。現在無法測試自己 – mdsumner

+0

@mdsumner這就是爲什麼lseq第二次被顛倒的原因。 – zwol

+0

好的,對不起,順便說一句,這是scale_y_continuous步驟,可能是以一種有問題的方式打破了多邊形 - 你可以看到它很好(但在y範圍內)通過發表評論 – mdsumner

回答

6

自從ggalt你可以直接做那些基於PROJ.4-預測:

library(ggplot2) 
library(sp) 
library(rworldmap) 
library(rgdal) 
library(ggalt) 
library(ggthemes) 

world <- fortify(getMap()) 
world <- subset(world, id != "Antarctica") 
lseq = seq(-60, 85, by=.25) 
boundary <- data.frame(
    long = c(rep(-180, length(lseq)), rep(180, length(lseq)), -180), 
    lat = c(lseq,     rev(lseq),   lseq[1])) 

gg <- ggplot() 
gg <- gg + geom_polygon(data=boundary, aes(x=long, y=lat), fill="#9AC5E3") 
gg <- gg + geom_map(data=world, map=world, 
        aes(long, lat, map_id=id), 
        color="#888888", fill="#f2caae", size=0.25) 
gg <- gg + coord_proj("+proj=wintri") 
gg <- gg + theme_map() 
gg 

enter image description here

與你原來真正的問題是你的多邊形限制,因爲你刻痕南極洲上方與邊界框:

lseq = seq(-53, 85, by=.25) 
boundary <- data.frame(
    long = c(rep(-180, length(lseq)), rep(180, length(lseq)), -180), 
    lat = c(lseq,     rev(lseq),   lseq[1])) 

gg <- ggplot() 
gg <- gg + geom_polygon(data=boundary, aes(x=long, y=lat), fill="#9AC5E3") 
gg <- gg + geom_map(data=world, map=world, 
        aes(long, lat, map_id=id), 
        color="#888888", fill="#f2caae", size=0.25) 
gg <- gg + coord_proj("+proj=wintri") 
gg <- gg + theme_map() 
gg 

enter image description here

儘管這本來是細跟coord_proj()反正:

gg + coord_proj("+proj=wintri", ylim=c(-60, 85)) 

enter image description here

所以,僅僅調整那些位:

lseq = seq(-53, 85, by=.25) 
boundary <- data.frame(
    long = c(rep(-180, length(lseq)), rep(180, length(lseq)), -180), 
    lat = c(lseq,     rev(lseq),   lseq[1])) 

gg <- ggplot() 
gg <- gg + geom_polygon(data=boundary, aes(x=long, y=lat), fill="#9AC5E3") 
gg <- gg + geom_map(data=world, map=world, 
        aes(long, lat, map_id=id), 
        color="#888888", fill="#f2caae", size=0.25) 
gg <- gg + coord_proj("+proj=wintri") 
gg <- gg + theme_map() 
gg 

enter image description here

,並沒有正常工作直接交叉企鵝:

gg <- ggplot() 
gg <- gg + geom_polygon(data=boundary, aes(x=long, y=lat), fill="#9AC5E3") 
gg <- gg + geom_map(data=world, map=world, 
        aes(long, lat, map_id=id), 
        color="#888888", fill="#f2caae", size=0.25) 
gg <- gg + coord_proj("+proj=wintri", ylim=c(-53, 85)) 
gg <- gg + theme_map() 
gg 

enter image description here

+0

我懷疑子集+沒有使用scale_y_limit是真正的修復在這裏 – mdsumner

+0

更新了更多信息/示例(超級壞頭冷,我昨晚太簡短了…道歉)。 – hrbrmstr

0

在使用「ggalt」是「正確答案」,這裏有一種方式來獲得你想要的東西 - 由第一裁剪出南極洲(雖然我不支持這一點,這是非常糟糕的) ,並使用'scale_y_discrete'。我不是很滿意gg-verse知道爲什麼,但我收集了南部邊界的連續不斷的斷裂,並以某種方式再次圍繞兩半畫出了路徑。離散種植可能選擇「最近」的座標並保持南部邊界。

我們確實需要更好的工具來跨越sp/ggplot2鴻溝,雖然我們有局部修復局部問題的動物園,但兩者並沒有適當的統一。 'ggalt'是更好的之一。

suppressPackageStartupMessages({ 
library(ggplot2) 
library(sp) 
library(rworldmap) 
library(rgdal) 
}) 
ll.to.wt <- function (points) 
as.data.frame(spTransform(SpatialPoints(points, CRS("+proj=longlat")), 
         CRS("+proj=wintri"))) 

## not much of a "world" without Antarctica . . 
badworld <- subset(spTransform(getMap(), CRS("+proj=wintri")), 
       !NAME == "Antarctica") 
world <- fortify(badworld) 
xlimits <- ll.to.wt(matrix(c(-180,180,0,0), nrow=2))$coords.x1 
ylimits <- ll.to.wt(matrix(c(0,0,-60,85), nrow=2))$coords.x2 
lseq = seq(-60, 85, by=.25) 
boundary <- ll.to.wt(data.frame(
long = c(rep(-180, length(lseq)), rep(180, length(lseq)), -180), 
lat = c(lseq,     rev(lseq),   lseq[1]))) 

ggplot() + 
geom_polygon(data=boundary, aes(x=long, y=lat), fill="#9AC5E3") + 
geom_map(data=world, map=world, aes(x=long, y=lat, map_id=id), 
     color="#888888", fill="#f2caae", size=0.25) + 
scale_x_continuous(limits=xlimits, expand=c(0,0)) + 
scale_y_discrete(limits=ylimits, expand=c(0,0)) + 
coord_equal() + 
theme(
axis.line=element_blank(), 
axis.text.x=element_blank(), 
axis.text.y=element_blank(), 
axis.ticks=element_blank(), 
axis.title.x=element_blank(), 
axis.title.y=element_blank(), 
legend.justification = c(0,0), # bottom of box 
legend.position  = c(0,0), # bottom of picture 
panel.background=element_blank(), 
panel.border=element_blank(), 
panel.grid.major=element_blank(), 
panel.grid.minor=element_blank(), 
panel.margin=unit(0, "lines"), 
plot.background=element_blank()) 
相關問題