在 ggplot 图中裁剪未使用的边距
Posted
技术标签:
【中文标题】在 ggplot 图中裁剪未使用的边距【英文标题】:Crop unused margin in a ggplot plot 【发布时间】:2019-09-10 10:28:28 【问题描述】:我创建了一个要保存为 svg 的 ggplot 世界地图。两者都工作正常。但是,我想更改/指定要保存的绘图区域。
我的代码如下:
raw_plot = ggplot(data = world_for_plot,
aes(x = long,
y = lat,
group = group,
fill = "black")) +
geom_polygon(aes(fill = results)) +
coord_equal(1.3, expand=F) +
scale_fill_continuous(na.value = '#F6F6F6', guide=F)
ggsave(file = "FOLDER\\LATAM.svg",
plot = raw_plot)
这给了我以下情节:
但是,我希望有一个文件/绘图在顶部和底部没有所有不必要的空白:
有什么想法吗?我已经发现coord_equal
命令会产生一些问题。没有它,情节将填满整个情节区域。不过,我需要coord_equal
命令,否则世界地图会显得有些拉长。
【问题讨论】:
在ggsave中指定你想要的图形的大小和形状 但这只是将情节“放大”或缩小,不是吗?例如。如果我指定宽度 = 和高度 = ...,它会改变绘图的比例,但不会裁剪顶部的 x 像素和底部的 x 像素。 如果您正确选择纵横比(以匹配绘图),额外的边距将消失 好的,我玩了一下,确实可以减少边距。但是,我没有设法完全删除它,并且根据 wdith/height 值,图中的比率当然会发生变化。由于我选择了 1.3 的 coord_equal 值,这应该是我的高/宽纵横比,但仍然留有一些余量。 【参考方案1】:如果您调整长度,这可能会起作用:
raw_plot + theme(plot.margin = margin(-2, 0, -2, 0, "cm"))
这里的边距顺序是上、右、下、左。
【讨论】:
【参考方案2】:我最近遇到了同样的问题,所以这是我为有同样问题的人提供的解决方案。
tmaptools
有一个函数get_asp_ratio
来计算空间对象的纵横比。我们可以使用该比率来移除任何地图的外边距。
library(ggplot2)
world <- rnaturalearth::ne_countries(returnclass = "sf") # to get the world map
ggplot() +
geom_sf(data = world) +
coord_sf(expand = FALSE) +
theme_void()
asp <- tmaptools::get_asp_ratio(world) # returns 2.070007
height <- 5
ggsave("world.svg", width = height * asp, height = height)
或者,如果我们不想依赖tmaptools
,我们可以使用ggsave
的包装器来创建自己的函数。这本质上是基于tmaptools::get_asp_ratio
函数。
deg_to_rad <- function(x)
(mean(x) * pi) / 180
get_aspect_ratio <- function(geometry)
if (!inherits(geometry, c("Spatial", "Raster", "sf", "sfc")))
stop('"geometry" must be of class "Spatial", "Raster", "sf" or "sfc".')
bbox <- sf::st_bbox(geometry)
xlim <- bbox[c(1, 3)]
ylim <- bbox[c(2, 4)]
xdeg <- diff(xlim)
ydeg <- diff(ylim)
if (xdeg == 0 || ydeg == 0)
asp <- 1
else
is_lon_lat <- sf::st_is_longlat(geometry)
asp <- unname((xdeg / ydeg) * ifelse(is_lon_lat, cos(deg_to_rad(ylim)), 1))
asp
save_ggmap <- function(filename, plot = last_plot(), width = NA, height = NA, ...)
geometry <- ggplot_build(plot)$data[[1]]$geometry
asp <- get_aspect_ratio(geometry)
if (is.na(width) && !is.na(height))
width <- height * asp
else if (is.na(height) && !is.na(width))
height <- width / asp
ggsave(filename, plot, width = width, height = height, ...)
我们可以像ggsave
一样使用这个函数。我们只需要指定width
或height
,该函数就会自动以正确的纵横比保存地图。
ggplot() +
geom_sf(data = world) +
coord_sf(expand = FALSE) +
theme_void()
save_ggmap("world.svg", width = 8)
要去除内边距,我们可以使用theme(plot.margin = margin(0, 0, 0, 0))
。
【讨论】:
以上是关于在 ggplot 图中裁剪未使用的边距的主要内容,如果未能解决你的问题,请参考以下文章