在函数内部使用时,gridsvg不起作用

时间:2015-07-16 22:55:53

标签: r svg ggplot2 r-grid

我想定义一个使用gridSVG包中的gridsvg设备的绘图保存功能。

.myBox
{
 background-image:url('....');
 background-repeat:no-repeat;
 background-size:cover;
}

但是如果我尝试使用该功能则不起作用。出现错误:

library(ggplot2)
library(gridExtra)    
mtcars$gear <- factor(mtcars$gear,levels=c(3,4,5),
                      labels=c("3gears","4gears","5gears")) 
mtcars$am <- factor(mtcars$am,levels=c(0,1),
                    labels=c("Automatic","Manual")) 
mtcars$cyl <- factor(mtcars$cyl,levels=c(4,6,8),
                     labels=c("4cyl","6cyl","8cyl")) 

myPlot <- qplot(mpg, data=mtcars, geom="density", fill=gear, alpha=I(.5), 
       main="Distribution of Gas Milage", xlab="Miles Per Gallon", 
       ylab="Density")

savePlot <- function(filename, plot, plotWidth = 15, plotHeight = 10){
    gridSVG:::gridsvg(name = filename, width = plotWidth, height = plotHeight)
    print(plot)
    dev.off(which = dev.cur())
}

但是,如果我从控制台执行这些步骤,则可以正常工作:

savePlot("~/Desktop/myplot.svg", myPlot)
 Show Traceback

 Rerun with Debug
 Error in eval(expr, envir, enclos) : object 'filename' not found 

有没有办法可以在另一个函数中使用gridsvg函数?

我想知道我是否可以在某些环境中使用eval来完成它。

谢谢, 本。

2 个答案:

答案 0 :(得分:2)

这是一个回旋处,但稍微有点原则,没有在全球环境中坚持一切(受到R Inferno中的范围讨论的启发):

library(gridSVG)

savePlot <- function(filename, plot, plotWidth = 15, plotHeight = 10){
    gridsvg(sys.frame(1))
    print(plot)
    grid.export(filename)
    grDevices::dev.off(which = dev.cur())
}

sys.frame(1)为我们提供了父上下文的评估框架(对于访问调用堆栈的函数的所有变体,都有一个正确的解释here。)

我将来自grid.export()的号召与dev.off()分开,因为来自gridSVG的所有dev.off基本上都是grid.export,然后调用{{1} }}。这也允许我们明确地将文件名提供给grDevices::dev.off

答案 1 :(得分:2)

多么好奇。 gridsvg似乎有一个eval(fncall[[i]])步骤,它遍历所有参数并分配它们,它必须在错误的环境中查找或者某些东西?我不确定这是gridSVG包的问题; eval - 语义总是让我困惑。

这是一个解决方法:如果你确保将参数-values-传递给gridsvg(而不是参数名称)它可以工作,虽然我同意这并不是特别优雅。你必须明确library(gridSVG)

library(gridSVG)
savePlot <- function(filename, plot, plotWidth = 15, plotHeight = 10){
    eval(call('gridsvg', name=filename, width=plotWidth, height=plotHeight))
    print(plot)
    dev.off(which = dev.cur())
}

所有这一切基本上是gridsvg而不是width=15,而不是width=plotWidth等等。{/ p>