R 以给定的纵横比保存绘图
我正在与非常棒的图书馆ggplot2合作。我通过使用R 以给定的纵横比保存绘图,r,ggplot2,gtable,R,Ggplot2,Gtable,我正在与非常棒的图书馆ggplot2合作。我通过使用coord\u fixed了解了如何设置绘图的纵横比。现在,我想将绘图保存为指定宽度(例如10厘米)的PDF格式,并计算出所需的高度。我不知道如何做到这一点。这可能吗?如果使用ggsave您只需指定图形设备的宽度和高度即可。如果指定绘图本身的纵横比,在图形设备中使用此纵横比(大致)也很好。保存pdf时高度和宽度的单位为英寸: ggplot(...) # make a plot here ggsave("plot.pdf", width = 10
coord\u fixed
了解了如何设置绘图的纵横比。现在,我想将绘图保存为指定宽度(例如10厘米)的PDF格式,并计算出所需的高度。我不知道如何做到这一点。这可能吗?如果使用ggsave
您只需指定图形设备的宽度和高度即可。如果指定绘图本身的纵横比,在图形设备中使用此纵横比(大致)也很好。保存pdf
时高度和宽度的单位为英寸:
ggplot(...) # make a plot here
ggsave("plot.pdf", width = 10)
现在只需将10厘米转换为英寸。此外,如果未指定某个纵横比,高度
,则不会强制将其设置为该纵横比。如果需要16:9的纵横比,可以根据宽度轻松计算高度:
ggplot(...) # make plot
width = 10
height = (9/16) * width
ggsave("plot.pdf", width = width, height = height)
如果您真的愿意,可以将其封装在函数中
编辑:关键是要同步绘图的纵横比(通过coord_fixed()
)和图形设备的纵横比。比如说
library(ggplot2)
ggplot(mtcars, aes(x = wt, y = mpg)) + geom_point() + coord_fixed()
ggsave("plt.png", width = 7, height = 7)
导致大量空白。而下面的ggsave
调用在纵横比上有更好的匹配性,但没有这么大的空白(很抱歉,图片太大了,无法设置最大大小:):
不确定,但像这样的东西是你想要的吗
ggplot(data.frame(x = seq(10), y = seq(10)), aes(x = x, y = y)) +
geom_point() +
coord_equal() +
theme(aspect.ratio = 1)
我觉得这很好:
ggsave("test.pdf", width = 4, height = 4)
空白太多,但图形本身的纵横比为1:
ggsave("test2.pdf", width = 4)
信息:
在图像中保存4 x 6.93您可以使用网格函数来计算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)
根据巴普蒂斯特的回答,我将他的代码精简为返回geotheory建议的纵横比。这对我来说方便多了,因为我要么想要一个固定的宽度或高度,要么通过一个现有的包装器函数传递所有内容,该函数还将字体添加到我的pdf中
哦,如果你使用了刻面,你需要手动考虑它们。按行除,按列乘。不确定是否有更好的方法
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]
}
ggGetAr一个更简单的解决方案是使用默认边距保存绘图,并使用默认边距修剪生成的png
当然,根据所使用的输出设备,修剪会有所不同。例如,如果是pdf,您可以按说明使用。我认为是Paul,但那是设备的大小,而不是绘图。添加标题、轴标签和图例等后,打印区域本身可能不是方形的,并且使用coord_fixed()
打印区域本身不会填充可用空间。我不知道除了调整打印窗口的大小之外还有什么好办法,直到ggsave()
不指定宽度就能得到10厘米宽的图像。谢谢你的回答。加文,这正是你在评论中指出的。我认为这是一个相当大的问题,必须手动裁剪每个地块。让我们拭目以待,看看是否有人提出了解决方案。谢谢你的回答,丹尼斯。不幸的是,这不合适,因为默认情况下,ggsave
仅采用当前绘图窗口的大小。谢谢您的回答,baptiste。似乎没有什么好办法。我接受了你的答案,因为我认为没有更好的办法出现。谢谢大家,这对我没用。当我把你的sizeit(p1,0.1)
plot保存(到pdf)时,输出奇怪地变换了轴。我认为最好使用一个函数,返回用于确定ggsave WITH和HEIGH参数的纵横比。
sizeit(p2, 2)
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]
}
require(ggplot2)
require(dplyr)
ggplot(iris, aes(Sepal.Length, Sepal.Width)) + geom_point() + coord_fixed(0.3)
ggsave("untrimmed.png")
system("convert untrimmed.png -trim -bordercolor white -border 20 reframed.png")