[R] [FORGED] Re: axis() after image.plot() does not work except if points() is inserted between

Paul Murrell paul at stat.auckland.ac.nz
Fri Jul 28 05:32:43 CEST 2017


Hi

I believe this is a clipping bug in the 'graphics' package.

A simpler version of the problem is this ...

plot(1:10)
mtext("margin-label", side=2, at=9, las=1, line=1, adj=0)
par(mfg=c(1,1))
## Only the text within the plot region is drawn
mtext("margin-label", side=2, at=9, las=1, line=1, adj=0, col="red")

I have committed a fix to the development version of R (r72982).

Paul

On 26/07/17 21:29, Marc Girondot via R-help wrote:
> Thanks... I agree that the problem was explained in the documentation 
> but I can't find a way to have axis() working even manipulating 
> par("plt") or with graphics.reset = TRUE:
> - adding graphics.reset=TRUE does not allow axis() to be shown;
> - I see that par()$plt is involved but it is the not sufficient to 
> explain why axis() works because if it is changed by hand, axes are not 
> shown.
> 
> Thanks for the trick about range(). I didn't notice that it has also a 
> na.rm option. It is more elegant.
> 
> Here is the code showing the various propositions and checks:
> 
> 
> library(fields)
> D <- matrix(c(10, 20, 25, 30, 12, 22, 32, 35, 13, 25, 38, 40), nrow=3)
> (pplt <- par()$plt)
> #### [1] 0.08844944 0.95469663 0.14253275 0.88541485
> 
> # original problem. Axis() not shown
> 
> image.plot(D, col=rev(heat.colors(128)),bty="n", xlab="Lines",
>             ylab="Columns", cex.lab = 0.5, zlim=range(D, na.rm=TRUE),
>             las=1, axes=FALSE)
> # Check the value of par()$plt; it is indeed modified
> par()$plt
> #### [1] 0.08844944 0.86408989 0.14253275 0.88541485
> # axis() does not work
> axis(1, at=seq(from=0, to=1, length=nrow(D)), labels=0:2, cex.axis=0.5)
> axis(2, at=seq(from=0, to=1, length=ncol(D)), labels=0:3, las=1, 
> cex.axis=0.5)
> 
> # I restore par("plt") to it original value
> par(plt=pplt)
> 
> # graphics.reset = TRUE. Axis() not shown
> 
> par()$plt
> ### [1] 0.08844944 0.95469663 0.14253275 0.88541485
> image.plot(D, col=rev(heat.colors(128)),bty="n", xlab="Lines",
>             ylab="Columns", cex.lab = 0.5, zlim=range(D, na.rm=TRUE),
>             las=1, axes=FALSE, graphics.reset = TRUE)
> # Check an effect on par()$plt. Indeed with graphics.reset = TRUE 
> par()$plt is restored
> par()$plt
> ### [1] 0.08844944 0.95469663 0.14253275 0.88541485
> # But the axes at not shown
> axis(1, at=seq(from=0, to=1, length=nrow(D)), labels=0:2, cex.axis=0.5)
> axis(2, at=seq(from=0, to=1, length=ncol(D)), labels=0:3, las=1, 
> cex.axis=0.5)
> 
> # Check an effect of points() on par()$plt
> # There is an effect
> # axes are shown
> 
> par()$plt
> ### [1] 0.08844944 0.95469663 0.14253275 0.88541485
> image.plot(D, col=rev(heat.colors(128)),bty="n", xlab="Lines",
>             ylab="Columns", cex.lab = 0.5, zlim=range(D, na.rm=TRUE),
>             las=1, axes=FALSE)
> points(1.5, 1.5, type="p")
> par()$plt
> ### [1] 0.08844944 0.86408989 0.14253275 0.88541485
> axis(1, at=seq(from=0, to=1, length=nrow(D)), labels=0:2, cex.axis=0.5)
> axis(2, at=seq(from=0, to=1, length=ncol(D)), labels=0:3, las=1, 
> cex.axis=0.5)
> 
> # Try to reproduce the effect of points() on par()$plt
> # axes are not shown. Then points() is doing something else !
> 
> image.plot(D, col=rev(heat.colors(128)),bty="n", xlab="Lines",
>             ylab="Columns", cex.lab = 0.5, zlim=range(D, na.rm=TRUE),
>             las=1, axes=FALSE)
> par(plt=c(0.08844944, 0.86408989, 0.14253275, 0.88541485))
> axis(1, at=seq(from=0, to=1, length=nrow(D)), labels=0:2, cex.axis=0.5)
> axis(2, at=seq(from=0, to=1, length=ncol(D)), labels=0:3, las=1, 
> cex.axis=0.5)
> # check that par("plt") is correctly setup
> par()$plt
> ### [1] 0.08844944 0.86408989 0.14253275 0.88541485
> 
> I think that it will remain a mystery !
> At least the trick with points() is working.
> 
> Thanks
> Marc
> 
> 
> Le 25/07/2017 à 13:03, Martin Maechler a écrit :
>>>>>>> Marc Girondot via R-help <r-help at r-project.org>
>>>>>>>      on Mon, 24 Jul 2017 09:35:06 +0200 writes:
>>      > Thanks for the proposition. As you see bellow, par("usr") is 
>> the same
>>      > before and after the points() (the full code is bellow):
>>      > ....
>>      >> par("usr")
>>      > [1] -0.2500000  1.2500000 -0.1666667  1.1666667
>>      >> # if you remove this points() function, axis will show nothing.
>>      >>
>>      >> points(1.5, 1.5, type="p")
>>      >> p2 <- par(no.readonly=TRUE)
>>      >> par("usr")
>>      > [1] -0.2500000  1.2500000 -0.1666667  1.1666667
>>      > ...
>>
>>      > I can reproduce it in Ubuntu and MacosX R Gui and Rstudio (R 
>> 3.4.1).
>>
>>      > Marc
>>
>>      > Here is the code:
>>      > library(fields)
>>      > par(mar=c(5,4.5,4,7))
>>      > D <- matrix(c(10, 20, 25, 30, 12, 22, 32, 35, 13, 25, 38, 40), 
>> nrow=3)
>>
>>      > p0 <- par(no.readonly=TRUE)
>>      > image.plot(D, col=rev(heat.colors(128)),bty="n", xlab="Lines",
>>      >           ylab="Columns", cex.lab = 0.5,
>>      >           zlim=c(min(D, na.rm=TRUE),max(D, na.rm=TRUE)),
>>      >           las=1, axes=FALSE)
>>      > p1 <- par(no.readonly=TRUE)
>>
>>      > par("usr")
>>      > par("xpd")
>>
>>      > # if you remove this points() function, axis will show nothing.
>>
>>      > points(1.5, 1.5, type="p")
>>      > p2 <- par(no.readonly=TRUE)
>>      > par("usr")
>>      > par("xpd")
>>
>>      > ##########
>>      > axis(1, at=seq(from=0, to=1, length=nrow(D)), labels=0:2, 
>> cex.axis=0.5)
>>      > axis(2, at=seq(from=0, to=1, length=ncol(D)), labels=0:3, las=1,
>>      > cex.axis=0.5)
>>
>>      > identical(p1, p2)
>>
>> Have you ever carefully read the detailed help page about image.plot()?
>> I haven't, but a cursory reading already shows me that the
>> author of the function did this partly on purpose:
>>
>>    > Side Effects:
>>    >
>>    >      After exiting, the plotting region may be changed to make it
>>    >      possible to add more features to the plot. To be explicit,
>>    >      ‘par()\$plt’ may be changed to reflect a smaller plotting 
>> region
>>    >      that has accommodated room for the legend subplot.
>>
>> Unfortunately, there it does _not_ mention the following :
>>
>> >From looking at its code, and then re-reading parts of the help page,
>> I see that there is a 'graphics.reset' argument which you can
>> set to TRUE in such a case:
>>
>>   image.plot(D, col=rev(heat.colors(128)),bty="n", xlab="Lines",
>>             ylab="Columns", cex.lab = 0.5,
>>             zlim= range(D, na.rm=TRUE),
>>        graphics.reset = TRUE, # <<<<< the solution
>>             las=1, axes=FALSE)
>>
>> Also note that
>>       zlim = range(D ...)
>> is infinitely more elegant than
>>       zlim = c(min((D, ...), max(D, ...)))
>>
>>
>> Martin Maechler
>> ETH Zurich (and R core)
>>
> 
> ______________________________________________
> R-help at r-project.org mailing list -- To UNSUBSCRIBE and more, see
> 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