在R中将地图和XY ggplot图表结合起来

10

我需要将一个代表考古遗址的地图与不同考古物件的XY ggplot图表结合起来。地图以tiff文件形式呈现,必须保持其比例。

首先,这是地图,并且用红色突出显示参考比例尺(例如,在X轴上,从-6000到-4000之间有20米的距离;在Y轴上,从900到2100之间有12米)。 enter image description here

我的ggplot图表是通过运行以下代码获得的:

archaeo <- ggplot() + 
    geom_ellipsis(data=Unit_H, 
        aes(x0 = X, y0 = Y, a = Diameter_E.W/2+250, b = Diameter_N.S/2+250, angle = 0), 
        lwd=0, col="darkgray", fill="gray", alpha=0.15) +     
    geom_ellipsis(data=Unit_H, 
        aes(x0 = X, y0 = Y, a = Diameter_E.W/2+120, b = Diameter_N.S/2+120, angle = 0), 
        lwd=0, col="darkgray", fill="gray", alpha=0.25) + 
    geom_ellipsis(data=Unit_H, 
        aes(x0 = X, y0 = Y, a = Diameter_E.W/2, b = Diameter_N.S/2, angle = 0), 
        lwd=0.5, col="darkgray", fill="gray", alpha=0.75) + 
    geom_point(data=Unit_H, aes(X, Y), size = 0.5) + 
    geom_point(data=Refits_H_trans, aes(x,y,group=sample, colour=factor(sample))) + 
    geom_line(data=Refits_H_trans, lwd=0.2, lty=1, aes(x,y, group=sample, colour=factor(sample))) + 
    coord_fixed() + 
    theme_bw() + 
    theme(legend.position="none") + 
    ggtitle("Unit H") + 
    xlim(-6600,-3800) + 
    ylim(400,2400)

得到的图表如下:

enter image description here

现在,我的问题是如何将地图作为ggplot的背景。我使用ggpubr中的background_image(),得到了以下结果:

map_levelH <- readPNG("Planta H-I.png")

Map.archaeo <- ggplot() + 
    background_image(map_levelH) + 
    geom_ellipsis(data=Unit_H, 
        aes(x0 = X, y0 = Y, a = Diameter_E.W/2+250, b = Diameter_N.S/2+250, angle = 0), 
        lwd=0, col="darkgray", fill="gray", alpha=0.15) +     
    geom_ellipsis(data=Unit_H, 
        aes(x0 = X, y0 = Y, a = Diameter_E.W/2+120, b = Diameter_N.S/2+120, angle = 0), 
        lwd=0, col="darkgray", fill="gray", alpha=0.25) + 
    geom_ellipsis(data=Unit_H, 
        aes(x0 = X, y0 = Y, a = Diameter_E.W/2, b = Diameter_N.S/2, angle = 0), 
        lwd=0.5, col="darkgray", fill="gray", alpha=0.75) + 
    geom_point(data=Unit_H, aes(X, Y), size = 0.5) + 
    geom_point(data=Refits_H_trans, aes(x,y,group=sample, colour=factor(sample))) + 
    geom_line(data=Refits_H_trans, lwd=0.2, lty=1, aes(x,y, group=sample, colour=factor(sample))) + 
    coord_fixed() + 
    theme_bw() + 
    theme(legend.position="none") + 
    ggtitle("Unit H") + 
    xlim(-6600,-3800) + 
    ylim(400,2400)

在此输入图像描述

如您所见,ggplot和地图的比例尺不匹配。因此,我的问题是:

  • 我该如何使用ggplot X轴和Y轴的值来进行地图配准?
  • 我需要保持图像的比例,以免扭曲它。我该如何做到这一点?我问这个问题是因为如果我更改xlim值,图像也会改变,并且其比例会改变。

我不知道足够多以给出完整的答案,但我相信你可以将图像转换为光栅并分配地理信息——坐标、投影等。在GIS Stack Exchange上也有相关问题。 - camille
我不确定我理解预期的输出。使用类似于 theme_void() 的方法删除 ggplot 的轴是否足够? - DJack
感谢您的评论。我会尝试使用“raster”。@DJack,我需要以ggplot的X和Y值为基准地理参考png图像,因此删除轴并不能保证图片能够很好地进行地理参考。还有其他想法吗? - antecessor
为此,您需要知道png和ggplot的投影(crs)。 - DJack
1个回答

1
我已经重新创建了一个简单的例子,其中存在这个问题:
library(tidyverse)

# create the background
bck_square <- data.frame(x=c(1,1,0,0),y=c(0,1,1,0))
p <- ggplot(bck_square, aes(x=x, y=y)) +
  geom_point(size=10, color="red") + 
  theme(panel.border=element_blank(), 
        panel.grid.major=element_blank(),
        panel.grid.minor=element_blank(),
        #panel.background=element_blank(), keep the background to see where image ends
        axis.text=element_blank(),
        axis.ticks=element_blank(),
        axis.title=element_blank())
p

enter image description here

我将保存图像以用作我的图表背景:
ggsave("temp.png",p)
img <- readPNG("temp.png")

使用ggpubr包中的background_image设置背景时,即使数据相同,旧正方形也与新正方形不对齐。这是预期的,因为ggsave会在图像周围添加一条细边框。
library(ggpubr)
ggplot(bck_square, aes(x, y)) +
  background_image(img) +
  geom_point()

enter image description here

然而,通过使用annotation_custom(请参见this指南),您可以调整图像的最小值和最大值。通过调整边框参数,我成功地使图像背景和图形对齐。
library(png)
library(grid)
min_border <- .064
max_border <- .061
ggplot(bck_square, aes(x, y)) +
  annotation_custom(g,xmin=-min_border, xmax=1+max_border, ymin=-min_border, ymax=1+max_border) +
  geom_point()

enter image description here

这种方法应该适用于tiff文件。另一个潜在的解决方案可能是使用rspatial进行空间数据转换(请参阅文档here),但这可能会使问题过于复杂化。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接