以给定的纵横比保存绘图 [英] Save plot with a given aspect ratio

查看:16
本文介绍了以给定的纵横比保存绘图的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用非常棒的库 ggplot2.我想出了如何使用 coord_fixed 设置绘图的纵横比.现在,我想将绘图保存为具有指定宽度(例如 10 厘米)的 PDF 并计算所需的高度.我没有弄清楚如何实现这一目标.这甚至可能吗?

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?

推荐答案

您可以使用网格函数来计算 ggplot grob 的完整大小,但有( 至少)两个警告:

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

默认情况下,绘图面板大小将为 0,因为它是根据它所在的设备(视口)即时计算的,而不是相反.

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.

话虽如此,下面的函数试图打开一个完全适合 ggplot 的设备,

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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆