Reputation: 36597
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
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