我正在使用非常棒的库ggplot2.我想通过使用如何设置绘图的纵横比coord_fixed
.现在,我想将绘图保存为具有指定宽度(例如10 cm)的PDF,并计算所需的高度.我没弄明白如何实现这一目标.这甚至可能吗?
bap*_*ste 12
您可以使用网格函数来计算ggplot grob的完整大小,但有(编辑:至少)两个警告:
将打开一个额外的设备窗口,进行单位转换
默认情况下,绘图面板大小为0,因为它意味着根据它所在的设备(视口)即时计算,而不是相反.
话虽这么说,以下函数试图打开一个完全符合ggplot的设备,
library(ggplot2)
library(grid)
sizeit <- function(p, panel.size = 2, default.ar=1){
gb <- ggplot_build(p)
# first check if theme sets an aspect ratio
ar <- gb$plot$coordinates$ratio
# second possibility: aspect ratio is set by the coordinates, which results in
# the use of 'null' units for the gtable layout. let's find out
g <- ggplot_gtable(gb)
nullw <- sapply(g$widths, attr, "unit")
nullh <- sapply(g$heights, attr, "unit")
# ugly hack to extract the aspect ratio from these weird units
if(any(nullw == "null"))
ar <- unlist(g$widths[nullw == "null"]) / unlist(g$heights[nullh == "null"])
if(is.null(ar)) # if the aspect ratio wasn't specified by the plot
ar <- default.ar
# ensure that panel.size is always the larger dimension
if(ar <= 1 ) panel.size <- panel.size / ar
g$fullwidth <- convertWidth(sum(g$widths), "in", valueOnly=TRUE) +
panel.size
g$fullheight <- convertHeight(sum(g$heights), "in", valueOnly=TRUE) +
panel.size / ar
class(g) <- c("sizedgrob", class(g))
g
}
print.sizedgrob <- function(x){
# note: dev.new doesn't seem to respect those parameters
# when called from Rstudio; in this case it
# may be replaced by x11 or quartz or ...
dev.new(width=x$fullwidth, height=x$fullheight)
grid.draw(x)
}
p1 <- ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + coord_fixed() +
theme(plot.background = element_rect(colour = "red"))
p2 <- p1 + aes(x = mpg, y = wt)
# need for an explicit dummy device open, otherwise it's a bit off
# for no apparent reason that I can understand
dev.new()
sizeit(p1, 0.1)
Run Code Online (Sandbox Code Playgroud)
sizeit(p2, 2)
Run Code Online (Sandbox Code Playgroud)
根据 baptiste 的回答,我精简了他的代码以返回 geotheory 建议的纵横比。这对我来说更方便,因为我想要一个固定的宽度或高度,并且还通过现有的包装函数传递所有内容,该函数还将字体添加到我的 pdf 中。
哦,如果您使用了 facet,则需要手动考虑它们。按行除以列乘以。不知道有没有更好的方法......
ggGetAr <- function(p, default.ar=-1){
gb <- ggplot_build(p)
# first check if theme sets an aspect ratio
ar <- gb$plot$coordinates$ratio
# second possibility: aspect ratio is set by the coordinates, which results in
# the use of 'null' units for the gtable layout. let's find out
g <- ggplot_gtable(gb)
nullw <- sapply(g$widths, attr, "unit")
nullh <- sapply(g$heights, attr, "unit")
# ugly hack to extract the aspect ratio from these weird units
if(any(nullw == "null"))
ar <- unlist(g$widths[nullw == "null"]) / unlist(g$heights[nullh == "null"])
if(is.null(ar)) # if the aspect ratio wasn't specified by the plot
ar <- default.ar
ar[1]
}
Run Code Online (Sandbox Code Playgroud)