[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