Greg Snow
2016-Mar-15 15:31 UTC
[Rd] [FORGED] Different results based on the order of arguments to par
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/-- Gregory (Greg) L. Snow Ph.D. 538280 at gmail.com
Paul Murrell
2016-Mar-15 20:10 UTC
[Rd] [FORGED] Different results based on the order of arguments to par
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/
Greg Snow
2016-Mar-15 21:45 UTC
[Rd] [FORGED] Different results based on the order of arguments to par
Paul, I am fine with not changing the par function, mainly mentioned it as a possibility in case someone else saw additional pitfalls, but nobody else has chimed in. What are your thoughts on adding an additional note to the help for par? it could make it more clear to call things like par(plt= before plot.new and things like par(usr= after plot.new. Your subplotadd function works for this case, but I don't want to think through all the possible combinations of the parameters that may need to be set depending on what changes are wanted. I plan to update the help page for subplot to make this more clear for people coming from that direction, I will probably include an example like subplot( {hist(rnorm(100)); abline(v=0, col='red')}, x='topright') as well to show that if you plan ahead you don't need to go back and can avoid the whole issue. Thanks for your comments, On Tue, Mar 15, 2016 at 2:10 PM, Paul Murrell <paul at stat.auckland.ac.nz> wrote:> 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/-- Gregory (Greg) L. Snow Ph.D. 538280 at gmail.com
Seemingly Similar Threads
- [FORGED] Different results based on the order of arguments to par
- [FORGED] Different results based on the order of arguments to par
- Different results based on the order of arguments to par
- [FORGED] Re: axis() after image.plot() does not work except if points() is inserted between
- Clipping using par(plt=..., xpd=FALSE) inconsistencies