[R] What's box() (exactly) doing?

William Dunlap wdunlap at tibco.com
Sat Jun 25 06:14:21 CEST 2016


Try this one:

myBox <- function (which = c("plot", "figure"), ...) {
   # draw filled rectangle where box() would draw open rectangle
    which <- match.arg(which)
    oldXpd <- par("xpd")
    on.exit(par(oldXpd))
    if (which == "plot") {
        do.call("rect", c(as.list(par("usr")[c(1, 3, 2, 4)]),
            list(...)))
    }
    else {
        mapLinearly <- function(x, from, to) {
            stopifnot(length(from) == 2, length(to) == 2)
            diff(to)/diff(from) * (x - from[1]) + to[1]
        }
        figX <- mapLinearly(c(0, 1), par("plt")[1:2], par("usr")[1:2])
        figY <- mapLinearly(c(0, 1), par("plt")[3:4], par("usr")[3:4])
        do.call("rect", c(as.list(c(figX, figY)[c(1, 3, 2, 4)]),
            list(...)))
    }
}

as in

> par(mfrow=c(3,3))
> for(i in 1:4)frame()
> plot(sunspots)
> box(which="plot", col="blue", lwd=5)
> box(which="fig", col="red", lwd=5)
> myBox(which="plot", col=adjustcolor("lightblue", alpha.f=0.3))
> myBox(which="fig", col=adjustcolor("pink", alpha.f=0.3))


Bill Dunlap
TIBCO Software
wdunlap tibco.com

On Fri, Jun 24, 2016 at 7:19 PM, Marius Hofert <marius.hofert at uwaterloo.ca>
wrote:

> Hi Jim,
>
> Here is a follow-up question: How would you replicate box("figure")
> (instead of box() = box("plot"))?
> I tried to fill the plotted box but there seems to be no argument to
> box("figure") that does that. If that's indeed the case, one could
> work again with rect() (thus replicating box("figure")), but how can
> one specify the exact location/width/height of the rectangle? (see
> example below)
>
> Cheers,
> M
>
> plot(NA, type = "n", ann = TRUE, axes = TRUE, xlim = 0:1, ylim = 0:1)
> box("figure", col = "red", lwd = 2) # how to fill?
>
> par(xpd = TRUE)
> width = 1.4 # obviously not correct...
> height <- width
> loc.x <- 0.5
> loc.y <- 0.5
> xleft <- loc.x-width/2
> xright <- loc.x+width/2
> ybottom <- loc.y-height/2
> ytop <- loc.y+height/2
> rect(xleft = xleft, ybottom = ybottom, xright = xright, ytop = ytop,
>      col = adjustcolor("grey80", alpha.f = 0.5))
> par(xpd = FALSE)
>
> On Fri, Jun 24, 2016 at 8:40 PM, Marius Hofert
> <marius.hofert at uwaterloo.ca> wrote:
> > Hi Jim,
> >
> > Thanks a lot, exactly what I was looking for.
> >
> > Cheers,
> > Marius
> >
> >
> >
> > On Thu, Jun 23, 2016 at 11:06 PM, Jim Lemon <drjimlemon at gmail.com>
> wrote:
> >> Hi Marius,
> >> There are a few things that are happening here. First, the plot area
> >> is not going to be the same as your x and y limits unless you say so:
> >>
> >> # run your first example
> >> par("usr")
> >> [1] -0.04  1.04 -0.04  1.04
> >>
> >> # but
> >> plot(NA, type = "n", ann = FALSE, axes = FALSE,
> >>  xlim = 0:1, ylim = 0:1,xaxs="i",yaxs="i")
> >> box()
> >> rect(xleft = 0, ybottom = 0, xright = 1, ytop = 1, col = "grey80")
> >> par("usr")
> >> [1] 0 1 0 1
> >>
> >> Second, the "rect" function is automatically clipped to the plot area,
> >> so you may lose a bit at the edges if you don't override this:
> >>
> >> par(xpd=TRUE)
> >> rect(...)
> >> par(xpd=FALSE)
> >>
> >> Finally your second example simply multiplies the first problem by
> >> specifying a layout of more than one plot. Applying the "xaxs" and
> >> "yaxs" parameters before you start plotting will fix this:
> >>
> >> par(xaxs="i",yaxs="i")
> >>
> >> Jim
> >>
> >> On Fri, Jun 24, 2016 at 12:29 PM, Marius Hofert
> >> <marius.hofert at uwaterloo.ca> wrote:
> >>> Hi,
> >>>
> >>> I would like to replicate the behavior of box() with rect() (don't ask
> why).
> >>> However, my rect()angles are always too small. I looked a bit into the
> >>> internal C_box but
> >>> couldn't figure out how to solve the problem. Below is a minimal
> >>> working (and a slightly bigger) example.
> >>>
> >>> Cheers,
> >>> Marius
> >>>
> >>> ## MWE
> >>> plot(NA, type = "n", ann = FALSE, axes = FALSE, xlim = 0:1, ylim = 0:1)
> >>> rect(xleft = 0, ybottom = 0, xright = 1, ytop = 1, col = "grey80") #
> >>> should match box()
> >>> box()
> >>>
> >>> ## Extended example
> >>>
> >>> ## Basic plot
> >>> my_rect <- function()
> >>> {
> >>>     plot(NA, type = "n", ann = FALSE, axes = FALSE, xlim = 0:1, ylim =
> 0:1)
> >>>     rect(xleft = 0, ybottom = 0, xright = 1, ytop = 1, col = "grey80")
> >>> # should match box()
> >>>     box()
> >>> }
> >>>
> >>> ## Layout
> >>> lay <- matrix(0, nrow = 3, ncol = 3, byrow = TRUE)
> >>> lay[1,1] <- 1
> >>> lay[2,1] <- 2
> >>> lay[2,2] <- 3
> >>> lay[2,3] <- 4
> >>> lay[3,3] <- 5
> >>> layout(lay, heights = c(1, 10, 1), widths = c(10, 1, 10))
> >>> layout.show(5) # => no space between rectangles; calls box() to draw
> the boxes
> >>>
> >>> ## Fill layout
> >>> par(oma = rep(0, 4), mar = rep(0, 4))
> >>> my_rect()
> >>> my_rect()
> >>> my_rect()
> >>> my_rect()
> >>> my_rect()
> >>> ## => spaces between rectangles => why?/how to avoid?
> >>>
> >>> ______________________________________________
> >>> 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.
>
> ______________________________________________
> 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.
>

	[[alternative HTML version deleted]]



More information about the R-help mailing list