You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用patchwork与ggplot2在R Markdown PDF中填充页面的问题

Patchwork排版地图的空白问题解决方案

我尝试用patchwork库排列3幅地图并输出PDF,要求组合后的地图占满6.5英寸的页面宽度,最大化单幅地图尺寸。单独绘图时地图能正常占满指定空间,但用patchwork排版后出现大量空白,调整边距的方法无效;同时还希望消除组合图中上方两幅图与下方图之间的空白。可复现代码及原效果如下:

原代码(含问题的组合绘图)

YAML文档头

---
title: "Testing"
author: "Erica Newton"
date: "2023-06-23"
output: pdf_document
---

加载依赖包与数据

library(ggspatial)
library(ggplot2)
library(patchwork)
library(sf)
library(terra)
library(raster)
library(tidyterra)
library(dismo)

nc <- st_read(system.file("shape/nc.shp", package = "sf"))
b2 <- rast(system.file("ex/bio16.grd", package = "dismo"))

单独绘图(正常响应宽高)

a <- ggplot(nc) + 
  geom_sf() +
  scale_x_continuous(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0)) +
  theme_void() 

b <- ggplot(nc) + 
  scale_x_continuous(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0)) +
  geom_sf(fill = "pink") +
  theme_void() 

(a + a) / b
c <- ggplot() + 
  geom_spatraster(data = b2) +
  scale_x_continuous(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0)) +
  theme_void() +
  theme(legend.position = "none",
        plot.margin = unit(c(0, 0, 0, 0), "null"),
        panel.background = element_rect(fill = "lightblue"))

c

存在空白问题的组合绘图

(a + b) / c + plot_annotation(theme = theme(plot.margin = margin()))

原效果截图

原组合地图效果


修正方案

核心问题原因

  1. 坐标系不匹配:nc(sf矢量数据)与b2(栅格数据)的坐标系不同,导致排版时比例错位,产生空白。
  2. 边距未彻底清除:仅单独设置子图边距或整体边距,未统一所有层级的边距设置。

修正后的完整代码

library(ggspatial)
library(ggplot2)
library(patchwork)
library(sf)
library(terra)
library(raster)
library(tidyterra)
library(dismo)

nc <- st_read(system.file("shape/nc.shp", package = "sf"))
b2 <- rast(system.file("ex/bio16.grd", package = "dismo"))
# 统一坐标系:将矢量数据转换为栅格数据的坐标系
nc <- st_transform(nc, st_crs(b2))
a <- ggplot(nc) + 
  geom_sf() +
  scale_x_continuous(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0)) +
  theme_void() 

b <- ggplot(nc) + 
  scale_x_continuous(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0)) +
  geom_sf(fill = "pink") +
  theme_void() 

c <- ggplot() + 
  geom_spatraster(data = b2) +
  scale_x_continuous(expand = c(0,0)) +
  scale_y_continuous(expand = c(0,0)) +
  theme_void() +
  theme(legend.position = "none",
        panel.background = element_rect(fill = "lightblue"))

# 修正后的组合排版
(a + b) / c +
  # 设置上下部分高度比例,消除中间空白
  plot_layout(heights = c(1, 1)) +
  # 清除组合图整体的外部边距
  plot_annotation(theme = theme(plot.margin = margin(0, 0, 0, 0))) +
  # 统一所有子图的内部边距为0
  & theme(plot.margin = unit(c(0, 0, 0, 0), "pt"))

修正要点

  • 统一坐标系:用st_transform()将矢量数据nc转换为与栅格数据b2相同的坐标系,确保所有地图的比例一致,避免错位空白。
  • 统一边距设置:通过&运算符为所有子图设置plot.margin = unit(c(0,0,0,0), "pt"),彻底清除子图内部边距;同时在plot_annotation()中清除组合图的外部边距。
  • 调整布局比例:使用plot_layout(heights = c(1,1))指定上下两部分的高度比例,让上下图紧密贴合,消除中间的空白区域。

内容的提问来源于stack exchange,提问作者Nova

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 10:22:03