有没有办法删除 ggplot 之外的空白?

dcu*_*e27 7 r spatial ggplot2 r-sf

我正在使用用于创建静态地图的代码来包含在闪亮的应用程序中。但我有一个问题,绘图大小比实际绘图大得多,因此布局看起来不正常。有什么办法可以减少绘图外部的空白吗?

如果可能的话,我希望输出只是情节本身。

我的意思是空白的绘制不佳的例子

# reprex
library(terra)
library(sf)
library(magrittr)
library(ggplot2)

lux <- vect(system.file("ex/lux.shp", package = "terra"))

p <- lux %>% 
  st_as_sf() %>%
  ggplot() +
  geom_sf(aes(fill = NAME_2), colour = "white", size = 0.2) +
  theme(legend.position = "None") +
# found online - removes the whitespace around the plot but not the external whitespace
  theme(plot.margin=grid::unit(c(0,0,0,0), "mm")) 

p
Run Code Online (Sandbox Code Playgroud)

che*_*123 9

您的绘图包含空白的原因是由于 对坐标系施加的约束geom_sf()。绘图的纵横比通常会自行调整以适应典型绘图中窗口的大小,但在 shapefile ( ) 的情况下sf,纵横比由特定坐标参考系或与该特定投影关联的 CRS确定。您之前在地图中已经看到过这种情况,由于尝试将地球表面投影到 2D 平面上,每张地图都会出现扭曲。

因此,geom_sf()会产生具有适当纵横比的地图。如果您的视图窗口或输出图像与该纵横比不匹配,则侧面或顶部将有空白来补偿。那么,解决问题的方法是更改​​绘图的纵横比(这看起来不正确并且不是一个好主意),或者让输出图像或窗口与绘图的纵横比匹配。

TL;DR - 用于tmaptools::get_asp_ratio()获取绘图对象的纵横比,然后使用该纵横比保存绘图图像。

现在提供一些解释性图像等,帮助说明为什么geom_sf()功能与 不同geom_polygon(),以及如何在代表性示例中解决问题。

地图使用geom_polygon()

除非您使用 固定绘图区域的比率coord_fixed(),否则geom_polygon()随着输出纵横比的变化,绘图区域将始终被挤压和拉伸。

library(ggplot2)

my_map <- map_data("usa")
p1 <-
  ggplot(my_map, aes(long, lat)) +
  geom_polygon(aes(group=group), fill='white', color='black') +
  ggtitle('USA Using geom_polygon()')
Run Code Online (Sandbox Code Playgroud)

这是一张正方形地图:

ggsave('p1_square.png', plot=p1, width=5, height=5)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

这是一个矩形地图:

ggsave('p1_rect.png', plot=p1, width=15, height=5)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

地图使用geom_sf()

相比之下,您可以看到geom_sf()无论输出大小如何,地图始终保持其纵横比。

library(sf)

world1 <- sf::st_as_sf(map('usa', plot = FALSE, fill = TRUE))
p2 <-
  ggplot() + geom_sf(data = world1, fill='white') + ggtitle('USA Using geom_sf()')
Run Code Online (Sandbox Code Playgroud)

方形输出:

ggsave('p2_square.png', plot=p2, width=5, height=5)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

矩形输出:

ggsave('p2_rect.png', plot=p2, width=15, height=5)
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

如何删除空格?

所以,现在应该很明显为什么有空格了……但是我们如何删除它呢? 答案是,您需要使用对象所使用的 CRS 给出的相同纵横比来保存绘图sf。您需要的是一种获取该信息的方法。st_crs()包中的函数sf可以获取 shapefile 使用的 CRS 的名称,但它不会直接给出纵横比。为此,您可以使用库get_asp_ratio()中的函数tmaptools,然后使用它来计算宽度/高度。这里需要注意的是,我们需要get_asp_ratio()sf 对象上使用,而不是在绘图对象上使用。在这种情况下,是world1又不是p2

plot_ratio <- get_asp_ratio(world1)
ggsave('p2_perfect.png', plot=p2, width = plot_ratio*5, height=5)
Run Code Online (Sandbox Code Playgroud)

这为我们提供了一个与地图的纵横比完美匹配的绘图输出:

在此输入图像描述