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

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

问题描述

我正在使用非常棒的库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屋!

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