Skip to content

Add points to subplots

7 messages · Luca Cerone, David Winsemius, Jim Lemon +1 more

#
Dear all,
I am running some analysis using the pamr package (available on CRAN).

One of the plots I produce is made using the function "pamr.plotcv".
This displays two plots in the same figure (using par(mfrow=c(2,1)).

When the figure is created, I would like to be able to add some points
and lines, to the top plot.

After producing the plot with pamr.cvplot, I have tried to add a line
doing something like:

par(mfg=c(1,1))
lines(c(3,3), c(0,1), col = "blue", lty = 3)

However this doesn't work and the line is shown in the bottom plot.
How can I add points and lines to the top plot?

Thanks a lot in advance for the help,

Cheers,
Luca
#
On Jun 12, 2014, at 8:06 AM, Luca Cerone wrote:

            
I think you would be better off hacking the code and inserting your desired annotations before the focus is moved to the second region. There are split screen methods that allow changing focus for base graphics, but I'm not aware of ones that use the par() controls.
#
Thanks David,
I already did this, but in case the code gets updated I will have to
re-add the annotation, which I do not think it is ideal.

I was just wondering if there is an easy solution to this.
Thanks a lot for the help,

Cheers,
Luca

2014-06-13 3:12 GMT+02:00 David Winsemius <dwinsemius at comcast.net>:

  
    
#
On Fri, 13 Jun 2014 12:02:34 PM Luca Cerone wrote:
Hi Luca,
I decided to try using the split.screen function, which I had previously 
tried without getting what I wanted. This example:

split.screen(c(2,1))
screen(1)
screen()
plot(1:7)
screen(2)
plot(1:6)
screen(1,FALSE)
screen()
points(x=7:1,y=1:7,col="red")

when run with no graphics devices currently open, seems to work and do 
what you want. When I first tried it on an open device (x11) it would not 
switch screens properly, remaining on the top (first) screen despite calls 
to screen() that reported that the screen had changed. I tried this after 
opening a png device and it also worked correctly, so I think that if you 
are careful to initialize the graphics device immediately before 
split.screen it should do it.

Jim
3 days later
#
I am not familiar with the pamr.plotcv function, but in general if it
uses par(mfrow=c(2,1)) to set up for the multiple plots then your
problem with going back to the first plot is that you have lost the
other information (such as user coordinates) needed to add to the 1st
plot.  You can see that with the following base graphics commands:

par(mfrow=c(2,1))
plot(runif(25),rnorm(25))
tmp <- par(no.readonly=TRUE)
hist(rnorm(1000))

par(mfg=c(1,1))
abline(h=0, col='red')

The horizontal line is at what would be 0 in the lower plot, not the
upper.  Since I saved the graphics parameters I can do the correct
thing with a command like:

par(mfg=c(1,1), plt=tmp$plt, usr=tmp$usr)
abline(h=0, col='blue')

You can see the new line is in the correct place.

Looking at the help for pamr.plotcv it does not look like it has any
nice built-in ways to save the plotting parameters (some functions
would let you plot just the top, edit, then plot just the bottom).
Bot there is a hook to the plot.new function that can let us work
around this.  Try the following:

mypars <- list()
updatepars <- function() {
n <- length( .GlobalEnv$mypars )
.GlobalEnv$mypars[[ n + 1 ]] <- par(no.readonly=TRUE)
}
setHook('before.plot.new', updatepars)

par(mfrow=c(2,1))
plot(runif(25),rnorm(25))
hist(rnorm(1000))

setHook('before.plot.new',NULL, 'replace' ) ## clean up

par( mfg=c(1,1), plt=mypars[[2]]$plt, usr=mypars[[2]]$usr )
abline( h=0, col='blue' )


This creates a global variable "mypars" that is an empty list (we
should really figure out a way without using the global, but my
current thoughts would make this much more complicated, any
suggestions are welcome).  Then it creates a small function that will
add the current results of 'par' to that list.  Then this function is
set as a hook to be run before 'plot.new' so that any new plot will
first save the previous parameter settings.  Now we run the plotting
commands and use the parameters that were saved into 'mypars'.  I
chose to save all the parameters from every old plot in case more than
what is shown is needed, this could be used to go back 3 or 4 plots if
more than just 2 are plotted.

Try this with pamr.plotcv to see if it works (you may need to set some
additional parameters depending on what all pamr.plotcv does).


Whether this is the easy solution or not can be debated.  Hope it helps,
On Thu, Jun 12, 2014 at 9:06 AM, Luca Cerone <luca.cerone at gmail.com> wrote:

  
    
1 day later
#
Hi Greg and Jim.
In the end I solved by modifying the function.
I was just wondering if there is some function similar to Matlab's subplot,
which let you change the active plot.

Next time I will run in the same issue I will try the split.screen
function proposed by Jim.

Thanks a lot for the help,
Cheers,
Luca

2014-06-17 18:00 GMT+02:00 Greg Snow <538280 at gmail.com>:

  
    
#
There is a subplot function in the TeachingDemos package, but its
purpose is to put a small plot somewhere inside of a large plot.  You
can use it to position 2 plots on a blank plot.  It does return the
information that you need to then go back and modify the individual
plots.  However, it does not work for a plotting function that itself
splits the plotting area into multiple plots (the split.screen option
will have the same problem).

If the function that you are running does "par(mfrow=c(2,1))"
internally then it will not play nicely with the other options.  If
the function just produces 2 plots and expects you to have run the par
command yourself (either mfrow or ask=TRUE, etc.) then you have more
options.  However if you use the split.screen functions then you will
need to have a way to call screen() before the 2nd plot.  The setHook
option may work for you there.
On Wed, Jun 18, 2014 at 10:15 AM, Luca Cerone <luca.cerone at gmail.com> wrote: