裁剪地图并保留 R 中的坐标点

问题描述 投票:0回答:1

我需要创建一个背景地图,然后使用

ggplot
添加坐标点。我的代码的简化版本:

library("ggplot2")
library("png")
library("grid")

#creating background map
map <- map_data("world")
bg <- subset(map, region %in% c("France", "Italy","Switzerland"))
bg_map<-ggplot(bg, aes(long, lat, group=group)) +
  geom_polygon() #+coord_quickmap(xlim = c(-5,15), ylim=c(35,55))

xlim = ((ggplot_build(bg_map)$layout$panel_scales_x[[1]]$range$range))
ylim = ((ggplot_build(bg_map)$layout$panel_scales_y[[1]]$range$range))
ggsave('map_backgroung.png', width = diff(xlim), height = diff(ylim),limitsize = FALSE, dpi=72)


#adding points
bg_map = readPNG('map_backgroung.png') 
capitals<-c("Rome","Paris","Bern")
Lat<-c(41.8947,48.8534,46.9481)
Long<-c(12.4811, 2.3488, 7.4474)
df<-data.frame(capitals,Lat,Long) 

MapCapitals= ggplot(df) + 
  annotation_custom(rasterGrob(bg_map, width=unit(1,"npc"), height=unit(1,"npc")), 
                    -Inf, Inf, -Inf, Inf) + # Background
  xlim(xlim[1],xlim[2]) + # x-axis Mapping
  ylim(ylim[1],ylim[2]) + # y-axis Mapping
  geom_point(aes(x=Long, y=Lat, color="red"), size=2) 

The position of the point is right.如果我使用

裁剪背景图
coord_quickmap(xlim = c(-5,15), ylim=c(35,55))

使用

ggplot
the points no longer match correctly the map 创建地图时。

不同的地图投影(例如

coord_map
)也不起作用。在没有问题的情况下裁剪背景图的正确方法是什么?

编辑:我不会同时生成背景图和点,因为在原始代码中,背景图和点都会使用一些

scale_fill
函数。然后我想使用
plot_gg
将 2D 地图转换为 3D 地图(点变成 3D 对象)。在我看来,在具有多个
plot_gg
对象的物体上使用函数
scale_fill
时,我会遇到问题,因为
plot_gg
不知道哪个对象应该变成 3 维的。

r ggplot2 coordinates geospatial
1个回答
0
投票

您的问题是因为您创建的对象本身不是空间对象,因此它们的相对位置似乎在您的方法中被独立处理。

绘制空间数据时,首先将它们转换为空间对象“几乎总是”更容易。这是因为 ggplot2 能够使用

geom_sf()
geom_raster()
coord_sf()
等函数解释空间对象。因此,在绘制空间对象时,它们都将具有相同的相对空间位置。
背景的分辨率比较粗糙,例如

resolution = 0.01

但是可以增加此值以获得更好看的图像。下面的示例图像也是低分辨率,因此较高的 dpi 将改善输出。

library(sf) # For simple feature spatial objects
library(terra) # For raster objects
library(tidyterra) # For plotting terra objects in ggplot2
library(dplyr) # For data wrangling/pipes
library(ggplot2) 
library(patchwork) # Side by side plot

# Create sf of background map
bg <- map_data("world") %>%
  filter(region %in% c("France", "Italy","Switzerland")) %>%
  st_as_sf(coords = c("long","lat")) %>%
  group_by(region, group) %>%
  summarise(geometry = st_combine(geometry), .groups = "drop") %>% 
  st_cast("POLYGON") %>%
  st_set_crs(4326) %>%
  ungroup() %>%
  st_union() %>% 
  st_as_sf() %>%
  mutate(landmass = "landmass")

# Get bg bbox for raster extent
st_bbox(bg)
#     xmin     ymin     xmax     ymax 
# -4.76250 36.68784 18.48584 51.09712 

#rasterize bg
bg <- rast(resolution = .01, 
           crs = "EPSG:4326", 
           xmin = -4.76250, 
           xmax = 18.48584, 
           ymin = 36.68784, 
           ymax = 51.09712) %>% 
  rasterize(bg, ., background = NA, "landmass")

# create point sf
capitals <- c("Rome","Paris","Bern")
Lat <- c(41.8947,48.8534,46.9481)
Long <- c(12.4811, 2.3488, 7.4474)

df <- data.frame(capitals, Lat, Long) %>%
  st_as_sf(coords = c("Long","Lat")) %>%
  st_set_crs(4326)
 
# Plot 
p1 <- ggplot() +
  geom_raster(data = bg,
              aes(x = x, y = y, fill = landmass),
              show.legend = FALSE) +
  geom_sf(data = df, colour = "red", size = 2) +
  scale_fill_manual(values = "black",
                    na.value = "transparent")

p2 <- ggplot() +
  geom_raster(data = bg,
              aes(x = x, y = y, fill = landmass),
              show.legend = FALSE) +
  geom_sf(data = df, colour = "red", size = 2) +
  scale_fill_manual(values = "black",
                    na.value = "transparent") +
  coord_sf(xlim = c(-5,15), ylim=c(35,55))

p1 + p2

© www.soinside.com 2019 - 2024. All rights reserved.