Gridsvg doesn't work when used inside a function

I want to define a plot save function that uses the gridsvg device from the gridSVG package.

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())
}

      

However, if I try to use the function, it doesn't work. Error result:

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

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

      

However, if I do these steps from the console, it works:

gridSVG::gridsvg(name = "~/Desktop/myPlot.svg", width = 15, height = 10)
myPlot
dev.off()

      

Can the gridsvg function be used from another function?

I wonder if I can do this using eval from some environment.

Thanks Ben.

+3


source to share


2 answers


Here's a circular, but slightly more principled way, without pushing everything into the global environment (inspired by the discussion in 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)

gives us a framework for evaluating the parent context (there is an explanation here for all options for functions that access the call stack).

I have separated the call grid.export()

from the call to dev.off()

, because essentially everything dev.off

from gridSVG is a call grid.export

, and then call grDevices::dev.off

. It also allows you to specify the filename directly grid.export

.

+2


source


How curious. gridsvg

seems to have a step eval(fncall[[i]])

where it goes through all the arguments and assigns them and it should be looking for the wrong environment or something? I'm not sure if this is a package problem gridsvg

; eval

-semantics always confuse me.

Here's a workaround: if you make sure the -values- get argument is passed in gridsvg

(and not in the argument names), it works, although I agree it's not particularly elegant. And you should explicitly 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())
}

      

Everything it does is essentially call gridsvg

with width=15

, not width=plotWidth

, etc.

+2


source







All Articles