[R] par("plt") behaving inconsistely? bug?

Murat Tasan mmuurr at gmail.com
Mon Oct 13 05:09:06 CEST 2014


Fair enough, thanks for the reply, Paul.
I guess my follow-up thought is just on some undocumented
inconsistencies with which drawing functions handle upstream par(plt)
changes.
box() and axis(), for example, doesn't seem to mind at all, while more
data-oriented commands, e.g. points(...), balk without either (i)
something like par(new=TRUE); plot.new(); , or (ii) box() or axis()
appearing upstream.
But, at the same time, if no plot.new() call has ever been made on the
current device, both box() and points() give the same (or similar)
"plot.new() hasn't been called yet" error.

I'm not complaining, rather just sharing observations on some
seemingly (to me, perhaps not to all!) undocumented inconsistencies in
behavior.
I love having the par(plt) functionality around, and I think your
'best practices' description for its use is great.
Perhaps some version of your post can be added to the man page for par(plt)?

Cheers and thanks again!

-murat


On Wed, Oct 8, 2014 at 8:16 PM, Paul Murrell <paul at stat.auckland.ac.nz> wrote:
> Hi
>
> The canonical poison is this ...
>
> par(plt)
> plot.new()
> ...
> par(plt)
> par(new=TRUE)
> plot.new()
> ...
> par(plt)
> par(new=TRUE)
> plot.new()
>
> The idea is to set up parameters that control the placement of a plot, e.g.,
> par(plt), and then start a plot, with plot.new().  If you want more than one
> plot on a page (and par(mfrow) does not suffice) then you set up new
> placement parameters, tell R not to start a new page, with par(new=TRUE),
> then start another plot, with plot.new().
>
> Your code does not follow the "spirit" of the R graphics model because it
> starts a plot with one set of placement parameters and then changes those
> placement parameters several times within the same plot (instead of starting
> a new plot for each new set of placement parameters).
>
> I had a look at the C code that leads to your "surprising" result and there
> is at least one infelicity in there, but I could not see a simple fix that
> would make your example "work" without a high risk of breaking other things.
> So I'm afraid my best advice is to change your code to work with the
> graphics system.
>
> The layout() function might provide a less unpleasant approach to having
> more than one plot region on the page, depending on how complex your
> arrangement of plot regions is.
>
> Another alternative is to use the 'grid' graphics package, which is designed
> to allow for the flexible creation of multiple regions, depending on what
> you want to draw in each of those regions.
>
> Paul
>
>
> On 10/07/14 15:33, Murat Tasan wrote:
>>
>> 6. iteratively downgrade to earlier versions of R until it's working
>> again... then try to diff out the offending source code change.
>> i can try this, but i probably won't get to it for at least a few weeks
>> :-/
>>
>> in the meantime, i'm tacking on box(lty = 0) to every par(plt = ...) call,
>> e.g.
>>>
>>> par("plt" = some_plt_coordinates); box(lty = 0)
>>
>>
>> in the short term, this works.
>> clip(...), a combination of par("new" = TRUE); plot.new(), and a whole
>> bunch of other kludges work, too... pick your poison :-)
>>
>> cheers and thanks!
>>
>> -murat
>>
>> On Mon, Oct 6, 2014 at 2:08 PM, Greg Snow <538280 at gmail.com> wrote:
>>>
>>> I believe that what is happening is that the clipping region is being
>>> reset when you call box, but not when you call rect.  If you insert
>>> the command "par(xpd=NA)" (or TRUE instead of NA) after the plot.new
>>> and use the rect commands then you can see both rectangles (because
>>> this turns the clipping off).  Working with the clipping region
>>> (indirectly in your case) is complex since some functions properly
>>> reset the region and others do not (and  making the others
>>> automatically reset it may cause other problems when they reset a
>>> clipping region that should not be reset).
>>>
>>> So the options are:
>>>
>>> 1 dive into the source code enough to figure out if fixing rect to
>>> work with the clipping region is simple or not and submitting a patch
>>> 2 wait for Prof Brian Ripley to notice this fact and do the above (he
>>> has fixed a couple of other functions when made aware)
>>> 3 use par(xpd=TRUE) (or NA) to not clip to the plotting region (this
>>> is simple, but will allow things to be drawn outside of the plotting
>>> region, on simple example is using abline)
>>> 4 use a function that properly sets the clipping region (such as box)
>>> before plotting anything else
>>> 5 call clip(0,1,0,1) (or with the actual user coordinates) to manually
>>> set the clipping region
>>> 6 other?
>>>
>>>
>>> On Mon, Oct 6, 2014 at 12:00 PM, Murat Tasan <mmuurr at gmail.com> wrote:
>>>>
>>>> Hi all -- I just encountered a behavior that I believe has changed
>>>> from previous versions, though I haven't chased back the last version
>>>> that behaves as my existing code expects quite yet.
>>>> Perhaps this is a bug, though perhaps I'm missing a subtle detail
>>>> somewhere in the documentation...
>>>>
>>>> Here's some code that works as expected (in R 3.1.1):
>>>>
>>>> ########################################
>>>> pdf()
>>>> plot.new()
>>>>
>>>> original_plt <- par("plt")
>>>>
>>>> plt_1 <- c(original_plt[1],
>>>>             original_plt[1] + (original_plt[2] - original_plt[1]) / 2,
>>>>             original_plt[3],
>>>>             original_plt[3] + (original_plt[4] - original_plt[3]) / 2)
>>>> par("plt" = plt_1)
>>>> plot.window(xlim = c(0, 1), ylim = c(0, 1))
>>>> box()
>>>> plt_2 <- c(plt_1[2],
>>>>             original_plt[2],
>>>>             plt_1[4],
>>>>             original_plt[4])
>>>> par("plt" = plt_2)
>>>> plot.window(xlim = c(0, 1), ylim = c(0, 1))
>>>> box()
>>>> par("plt" = original_plt)
>>>> box(lty = 2)
>>>> dev.off()
>>>> ########################################
>>>>
>>>> This will draw 3 boxes... one in the lower left corner (specified by
>>>> plt_1), one in the top right corner (specified by plt_2), and one
>>>> dotted box around the full plot box (original_plt).
>>>>
>>>> Now, if you replace the first two box() calls by: rect(0, 0, 1, 1),
>>>> only the lower-left rectangle is drawn.
>>>> If you _add_ rect(0, 0, 1, 1) after each box() call, all boxes and
>>>> rectangles are correctly drawn.
>>>>
>>>> It seems that after setting plt once, subsequent plt alterations put
>>>> the device into a state that will permits drawing of _some_ things
>>>> (e.g. box()), but not other things (e.g. rect, lines, points).
>>>>
>>>> A kludge to fix this is to call box(col = "white")... but that's quite
>>>> the kludge, indeed!
>>>> Axis() works just like box(), too... but I haven't exhausted which
>>>> drawing functions work and which don't.
>>>>
>>>> I'd classify this is a bug, but I thought I'd check here first.
>>>> I've also only checked this so far with the pdf() device, so I don't
>>>> know if it is somehow device-specific.
>>>>
>>>> I detected this because some existing code (that worked on some
>>>> earlier version of R, sorry that I don't know which one yet...) has
>>>> suddenly stopped working!
>>>>
>>>> Cheers!
>>>>
>>>> -murat
>>>>
>>>> ______________________________________________
>>>> R-help at r-project.org mailing list
>>>> https://stat.ethz.ch/mailman/listinfo/r-help
>>>> PLEASE do read the posting guide
>>>> http://www.R-project.org/posting-guide.html
>>>> and provide commented, minimal, self-contained, reproducible code.
>>>
>>>
>>>
>>>
>>> --
>>> Gregory (Greg) L. Snow Ph.D.
>>> 538280 at gmail.com
>>
>>
>> ______________________________________________
>> R-help at r-project.org mailing list
>> https://stat.ethz.ch/mailman/listinfo/r-help
>> PLEASE do read the posting guide
>> http://www.R-project.org/posting-guide.html
>> and provide commented, minimal, self-contained, reproducible code.
>>
>
> --
> 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/



More information about the R-help mailing list