由ggplot制作的自动裁剪多面图
Posted
技术标签:
【中文标题】由ggplot制作的自动裁剪多面图【英文标题】:autocrop faceted plots made by ggplot 【发布时间】:2018-01-25 15:22:02 【问题描述】:在 ggplot 中制作多面图并更改纵横比时,通常在图形的左右或上下都有很多空白。例如:
library(ggplot2)
df <- data.frame(x=rep(1,3), y=rep(1,3), z=factor(letters[1:3]))
p <- ggplot(df, aes(x, y)) + geom_point() + coord_fixed(ratio=1) + facet_grid(z ~ .)
ggsave("plot.jpg", p, scale=1, device="jpeg")
有没有办法自动裁剪图形?
【问题讨论】:
您是指多面图之间的空白,还是整个图周围的空白?对于前者,这些应该会有所帮助:***.com/questions/22945651/… & ***.com/questions/30983752/…。对于后者,我相信 ggsave 默认为您当前图形设备的尺寸,除非您指定高度和宽度。您是否正在寻找一种方法来根据您的情节自动获得合理的高度/宽度规范? 我指的是整个地块周围的空间。我会对自动获取 ggsave 的高度/宽度规范的方法非常感兴趣。 【参考方案1】:这就是我想出的。我在您的样品上对其进行了测试,它在那里似乎可以正常工作,但如果它在其他地方发生故障,请提前道歉。我不得不深入研究 grob 版本的宽度/高度信息,并且根据情节是否为多面体,“单位”的属性信息位于不同的位置。
希望对 grid 包的 unit
对象更精通的人可以参与进来,但这就是我所拥有的:
# Note that you need to set an upper limit to the maximum height/width
# that the plot can occupy, in the max.dimension parameter (defaults to
# 10 inches in this function)
ggsave_autosize <- function(filename, plot = last_plot(), device = NULL, path = NULL, scale = 1,
max.dimension = 10, units = c("in", "cm", "mm"),
dpi=300, limitsize = TRUE)
sumUnitNull <- function(x)
res <- 0
for(i in 1:length(x))
check.unit <- ifelse(!is.null(attr(x[i], "unit")), attr(x[i], "unit"),
ifelse(!is.null(attr(x[i][[1]], "unit")), attr(x[i][[1]], "unit"), NA))
if(!is.na(check.unit) && check.unit == "null") res <- res + as.numeric(x[i])
return(res)
# get width/height information from the plot object (likely in a mixture of different units)
w <- ggplotGrob(plot)$widths
h <- ggplotGrob(plot)$heights
# define maximum dimensions
w.max <- grid::unit(max.dimension, units) %>% grid::convertUnit("in") %>% as.numeric()
h.max <- grid::unit(max.dimension, units) %>% grid::convertUnit("in") %>% as.numeric()
# sum the inflexible size components of the plot object's width/height
# these components have unit = "in", "mm", "pt", "grobheight", etc
w.in <- w %>% grid::convertUnit("in") %>% as.numeric() %>% sum()
h.in <- h %>% grid::convertUnit("in") %>% as.numeric() %>% sum()
# obtain the amount of space available for the flexible size components
w.avail <- w.max - w.in
h.avail <- h.max - h.in
# sum the flexible sized components of the plot object's width/height
# these components have unit = "null"
w.f <- sumUnitNull(w)
h.f <- sumUnitNull(h)
# shrink the amount of avilable space based on what the flexible components would actually take up
if(w.f/h.f > w.avail/h.avail) h.avail <- w.avail/w.f*h.f else w.avail <- h.avail/h.f*w.f
w <- w.in + w.avail
h <- h.in + h.avail
ggsave(filename, plot = plot, device = device, path = path, scale = scale,
width = w, height = h, units = units, dpi = dpi, limitsize = limitsize)
p <- ggplot(mpg, aes(displ, cty)) + geom_point() + coord_fixed(ratio=1)
p <- p + facet_grid(. ~ cyl)
ggsave("pOriginal.png", p + ggtitle("original"))
ggsave_autosize("pAutoSize.png", p + ggtitle("auto-resize"))
ggsave_autosize("pAutoSize8.png", p + ggtitle("auto-resize, max dim = 8in x 8in"), max.dimension = 8, units = "in")
没有裁剪的原始版本。左边/右边有黑色空间:
自动裁剪的版本。高度 = 10 英寸:
自动裁剪的版本。高度 = 8 英寸(因此字体看起来稍大):
【讨论】:
以上是关于由ggplot制作的自动裁剪多面图的主要内容,如果未能解决你的问题,请参考以下文章