From paul at stat.auckland.ac.nz  Tue Mar 15 21:10:33 2016
From: paul at stat.auckland.ac.nz (Paul Murrell)
Date: Wed, 16 Mar 2016 09:10:33 +1300
Subject: [Rd] [FORGED] Different results based on the order of arguments
 to par
In-Reply-To: <CAFEqCdxki2D5QoRc4+iJpxofvcmY0n2cu0B52GXsMCpHwkrK6Q@mail.gmail.com>
References: <CAFEqCdyG5WRaPkKn9MQ4vyqN5sKpTfbx3AtyEt9_JP6qy51+oA@mail.gmail.com>
	<56E75FB6.7020808@stat.auckland.ac.nz>
	<CAFEqCdxki2D5QoRc4+iJpxofvcmY0n2cu0B52GXsMCpHwkrK6Q@mail.gmail.com>
Message-ID: <56E86C39.5070904@stat.auckland.ac.nz>

Hi

The main issue here is that the 'graphics' package has no real concept 
of going back to a previous plot (the 'grid' package has explicit 
support for that sort of thing).  In 'graphics' you can only go forwards 
to the next plot;  you can fake going back by creating a new plot that 
is like a previous plot.

par(plt=, usr=) is not designed to return you to a previous plot.
If it sounds like I am reluctant to change the behaviour of par(plt=, 
usr=) to support your use case, that is probably because I am.

You could add examples and warnings to subplot() documentation about 
this behaviour, but ideally users would not be encouraged to do this at all.

I would prefer to see something along the lines of ...

   hist(rexp(1000), main='')
   abline( v=1, col='red')

   sp.par <- subplot(hist(rnorm(100), main=''), x='topright')

   subplotadd <- function(fun, pars) {
       par(new=TRUE)
       par(pars['plt'])
       plot.new()
       par(pars['usr'])
       fun
   }

   subplotadd(abline(v=0, col='red'), sp.par)


Paul


On 16/03/16 04:31, Greg Snow wrote:
> Paul,
>
> I was trying to make a minimal self contained example, but I guess I
> went too far on the minimizing.  The original problem came from code
> more like:
>
> library(TeachingDemos)
>
> hist(rexp(1000), main='')
> abline( v=1, col='red')
>
> sp.par <- subplot(hist(rnorm(100), main=''), x='topright')
>
> op <- par(sp.par[c('usr', 'plt')])
> abline(v=0, col='red')
> par(op)
>
> and so plot.new, plot.window, etc. are called as part of the sub plot
> (specifically by hist(rnorm(100))) and I am trying to go back and add
> a reference line to the subplot so the user coordinates need to be set
> back to match the subplot (and the plotting region needs to be set so
> that the line is clipped appropriately).  With the code as above the
> user coordinates are not changed appropriately, in fact if 'xpd=NA' is
> added to the par call then the vertical line is added at 0 on the big
> histogram, not the little one as planned.
>
> If the order is changed in the call to par ( op <-
> par(sp.par[c('plt','usr')]) ) then everything works as planned.  It
> just seems a potential danger to have different behavior when the
> order of the arguments change without this fact at least documented.
>
> Maybe a warning and additional examples in the subplot documentation
> will be sufficient, since nobody else seems to have complained about
> this yet.  But, I am vain enough to think that somewhere in the world
> there is someone else who will make as stupid a mistake as me, so
> wanted to make others aware.  If nothing else, the next person (which
> may be forgetful future me) may see this in a search and at least know
> to order the arguments correctly.
>
>
> On Mon, Mar 14, 2016 at 7:04 PM, Paul Murrell <paul at stat.auckland.ac.nz> wrote:
>> Hi
>>
>> I'm going to try to blame user error here.
>>
>> par(usr) is used to reset the coordinates on the CURRENT plot.
>>
>> par(plt) is used to specify the location of the NEXT plot.
>>
>> The correct approach should be to set up the location for the next plot,
>> start a new plot, set up coordinates on the new plot.
>>
>> Neither of your examples performs the "start a new plot" step.
>>
>> I would expect to see something like ...
>>
>> dev.new()
>> hist(rexp(100))
>> # Set up location of new plot
>> par(plt=c(0.5,0.9,0.5,0.77))
>> # Avoid new page
>> par(new=TRUE)
>> # Start new plot
>> plot.new()
>> # Set up coordinates on new plot
>> # (though plot.window() might be better here)
>> par(usr=c(0,1,0,1))
>> # Start drawing
>> box()
>> points(c(0,1), c(0,1), pch=16, col='red', cex=3)
>>
>> Is there a good argument against doing that?
>>
>> Paul
>>
>>
>> On 15/03/16 10:27, Greg Snow wrote:
>>>
>>> I ran into this issue when trying to modify a subplot (subplot
>>> function in the TeachingDemos package), but here is a more minimal
>>> example of the issue (I don't know that it is serious enough to call a
>>> bug):
>>>
>>> This code works how I expect:
>>>
>>> dev.new()
>>> hist(rexp(100))
>>>
>>> par(plt=c(0.5,0.9,0.5,0.77), usr=c(0,1,0,1))
>>>
>>> box() # show new plt region
>>> points(c(0,1), c(0,1), pch=16, col='red', cex=3)
>>>
>>> it creates a histogram then changes the plotting region so that I can
>>> add an annotation, changes the user coordinates within the new region,
>>> then plots some points using the new coordinate system.
>>>
>>> But if I change the order of the arguments to par like so:
>>>
>>> dev.new()
>>> hist(rexp(100))
>>>
>>> par(usr=c(0,1,0,1), plt=c(0.5,0.9,0.5,0.77))
>>>
>>> box() #show new plt region
>>> points(c(0,1), c(0,1), pch=16, col='red')
>>>
>>> then the points do not show up (or if we add xpd=NA to the par call
>>> then we see them outside of the plotting region).  So clearly the
>>> behavior of par depends on the order of the arguments specified.
>>>
>>> This is not explicitly documented, though there is a hinting at the
>>> behavior in the note on the par help page (it was following this
>>> warning that led to me first encountering the issue, since I was
>>> specifying only the parameters that I needed, not everything, and
>>> happened to specify usr before plt), but "usr" is not included in the
>>> list in the note (because it does something different from what the
>>> note is specifically warning about).
>>>
>>>
>>> I see a few different potential responses to this issue:
>>>
>>> 1. consider that this is a rare enough issue that only Greg Snow will
>>> ever care and he has already learned the lesson, so do nothing (other
>>> than laugh at Greg when he forgets and has to remember to properly
>>> order his par arguments).
>>>
>>> 2. Since this came up as an issue with subplot, force the author of
>>> subplot and the TeachingDemos package to add a note or warning to the
>>> documentation for that function.
>>>
>>> 3.  Expand the note on the help page for par (or add another note)
>>> that warns that the order of the parameters matters and to therefore
>>> be careful in which order you specify arguments (probably with some
>>> detail on the suggested ordering).  While there will be many users who
>>> never read this, we will at least be able to point to the note if
>>> anyone else is affected by this issue.
>>>
>>> 4. Modify the par function to reorder the list created from its args
>>> so that they are evaluated in a consistent order (and probably add
>>> documentation to the help page to this effect).
>>>
>>>
>>> Thoughts?
>>>
>>>
>>>
>>>
>>
>> --
>> Dr Paul Murrell
>> Department of Statistics
>> The University of Auckland
>> Private Bag 92019
>> Auckland
>> New Zealand
>> 64 9 3737599 x85392
>> paul at stat.auckland.ac.nz
>> http://www.stat.auckland.ac.nz/~paul/
>
>
>

-- 
Dr Paul Murrell
Department of Statistics
The University of Auckland
Private Bag 92019
Auckland
New Zealand
64 9 3737599 x85392
paul at stat.auckland.ac.nz
http://www.stat.auckland.ac.nz/~paul/



[Rd] [FORGED] Different results based on the order of arguments to par
Paul Murrell