Suraj
Suraj

Reputation: 36597

Where does recordPlot() store par() and layout() for first plot?

In the following recorded plot, I cannot find the instruction that constructs the layout and sets the par() settings before the first plot.new call()

library( PerformanceAnalytics )
data( managers )

# write the plot to the open device
suppressWarnings(charts.RollingRegression(managers[, 1:6], managers[, 8, drop=FALSE], Rf = .04/12, colorset = rich6equal, legend.loc="topleft"))

# record = investigate the primitive calls.  notice no par() nor layout() before the first call to plot.new()
recorded = recordPlot()
lapply(recorded[[1]], "[[", 1 )

# as a result, the following creates one plot per page, not 3 on the same page:
lapply( recorded[[ 1 ]] , function( x ) { do.call( x[[ 1 ]] , as.list( x[[ 2 ]] ) ) } )

Perhaps this is encoded in recorded[[ 2 ]] which looks like some kind of encoded raw data? If so, how could I grab the insructions prior to the first plot.new() from the raw data?

Edit
Warning: dirty hack.
If you want to encode the initial state in the instruction list, here's how:

tryCatch( dev.off() , error = function( e ) {} )
plot.new()
par( new = TRUE )
originalLayoutFunction = graphics:::layout
graphicsEnvironment = as.environment( "package:graphics" )
newLayoutFunction = function( ... )
{
    originalLayoutFunction( ... )
    par( mfg = c( 1 , 1 ) )
}

unlockBinding( "layout" , env = graphicsEnvironment )
assign( "layout" , newLayoutFunction , envir = graphicsEnvironment )
lockBinding( "layout" , env = graphicsEnvironment )

tryCatch( YOUR_PLOT_CALL_HERE , finally = 
                                { 
                                    unlockBinding( "layout" , env = graphicsEnvironment )
                                    assign( "layout" , originalLayoutFunction , env = graphicsEnvironment )
                                    lockBinding( "layout" , env = graphicsEnvironment )                                    
                                } )
recordedPlot = recordPlot()
dev.off()

Upvotes: 1

Views: 1156

Answers (1)

Josh O'Brien
Josh O'Brien

Reputation: 162441

You're probably right about what's in recorded[[2]]. My suspicion is that it contains the SEXP which "nicely hides the internals" referenced in this comment from the R sources:

/****************************************************************
 * GEcreateSnapshot
 ****************************************************************
 */

/* Create a recording of the current display,
 * including enough information from each registered
 * graphics system to be able to recreate the display
 * The structure created is an SEXP which nicely hides the
 * internals, because noone should be looking in there anyway
 * The product of this call can be stored, but should only
 * be used in a call to GEplaySnapshot.
 */

A bit further down in the same file ($SRC_HOME/src/main/engine.c) is another possibly illuminating passage.

Like the comment above (and like the recordPlot help file), it too comes with a strongish admonition not to try mucking around with the objects stored by recordPlot(). "Here be dragons", they all say, and it looks like you are starting to meet them that were warned about ;)

/****************************************************************
 * GEplaySnapshot
 ****************************************************************
 */

/* Recreate a saved display using the information in a structure
 * created by GEcreateSnapshot.
 *
 * The graphics engine assumes that it is getting a snapshot
 * that was created in THE CURRENT R SESSION
 * (Thus, it can assume that registered graphics systems are
 *  in the same order as they were when the snapshot was
 *  created -- in patricular, state information will be sent
 *  to the appropriate graphics system.)
 * [With only two systems and base registered on each device at
 * creation, that has to be true: and grid does not save any state.]
 *
 *  It also assumes that the system that created the snapshot is
 *  still loaded (e.g. the grid namespace has not been unloaded).
 *
 * It is possible to save a snapshot to an R variable
 * (and therefore save and reload it between sessions and
 *  even possibly into a different R version),
 * BUT this is strongly discouraged
 * (in the documentation for recordPlot() and replayPlot()
 *  and in the documentation for the Rgui interface on Windows)
 */

Upvotes: 3

Related Questions