以给定的宽高比保存绘图 [英] Save plot with a given aspect ratio
问题描述
我正在使用非常棒的库ggplot2。我想通过使用 coord_fixed
来设定图的纵横比。现在,我想将绘图保存为指定宽度(例如10厘米)的PDF,并计算所需的高度。我没有弄清楚如何实现这一点。这甚至可能吗?
您可以使用网格函数来计算ggplot grob的完整大小,但有(编辑:至少)两个注意事项:
-
一个额外的设备窗口将打开,转换
-
默认情况下,绘图面板大小将为0,因为它意味着根据它的设备(视口)实时计算而不是相反。这就是说,下面的函数试图打开一个精确匹配ggplot的设备,
b
$ b
library(ggplot2)
库(网格)
sizeit< - function(p,panel.size = 2,default.ar = 1){
gb< - ggplot_build(p)
#首先检查主题是否设置宽高比
ar < - gb $ plot $ coordinates $ ratio
#第二种可能性:纵横比由坐标设置,这导致
#使用'null'单位作为gtable布局。让我们找出
g < - ggplot_gtable(gb)
nullw < - sapply(g $ widths,attr,unit)
nullh < - sapply(g $ heights,attr, 单元)
#丑陋的黑客从这些奇怪的单元中提取纵横比
if(any(nullw ==null))
ar < - unlist g $ widths [nullw ==null])/ unlist(g $ heights [nullh ==null])
if(is.null(ar))#如果长宽比wasn (t)由绘图指定
ar < - default.ar
#确保panel.size总是较大的尺寸
if(ar< = 1)面板。 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 sizegrob,class(g))
g
}
print.sizedgrob< - function(x){
#note:dev。新的似乎没有尊重这些参数
#当ca来自Rstudio;在这种情况下,
#可以被x11或石英或...代替
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(color =red))
p2 < - p1 + aes(x = mpg,y = wt)
#需要显式虚拟设备打开,否则它有点关闭
#无明显理由,我可以理解
dev.new()
sizeit(p1,0.1)
sizeit(p2,2)
I'm working with the really awesome library ggplot2. I figured out how to set the aspect ratio of a plot by using coord_fixed
. Now, I'd like to save the plot to a PDF with a specified width (e.g 10 cm) and let required height get calculated. I did not figure out how to achieve this. Is this even possible?
You can use grid functions to calculate the full size of the ggplot grob, but there are (edit: at least) two caveats:
an extra device window will open, to do the unit conversion
the plot panel size will be 0 by default, as it is meant to be calculated on-the-fly according to the device (viewport) it lives in, not the opposite.
That being said, the following function attempts to open a device that fits the ggplot exactly,
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)
sizeit(p2, 2)
这篇关于以给定的宽高比保存绘图的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!