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 >> stat.ethz.ch/mailman/listinfo/r-help >> PLEASE do read the posting guide R-project.org/posting-guide.html >> and provide commented, minimal, self-contained, reproducible code.
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 >>> stat.ethz.ch/mailman/listinfo/r-help >>> PLEASE do read the posting guide R-project.org/posting-guide.html >>> and provide commented, minimal, self-contained, reproducible code.
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 > >>> stat.ethz.ch/mailman/listinfo/r-help > >>> PLEASE do read the posting guide > 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 > stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide > R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code. >[[alternative HTML version deleted]]
You can use the grconvertX and grconvertY functions to find the coordinates (in user coordinates to pass to rect) of the figure region (or other regions). Probably something like: grconvertX(c(0,1), from='nfc', to='user') grconvertY(c(0,1), from='nfc', to='user') On Fri, Jun 24, 2016 at 8: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 >>>> stat.ethz.ch/mailman/listinfo/r-help >>>> PLEASE do read the posting guide 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 > stat.ethz.ch/mailman/listinfo/r-help > PLEASE do read the posting guide R-project.org/posting-guide.html > and provide commented, minimal, self-contained, reproducible code.-- Gregory (Greg) L. Snow Ph.D. 538280 at gmail.com
On Mon, Jun 27, 2016 at 5:42 PM, Greg Snow <538280 at gmail.com> wrote:> You can use the grconvertX and grconvertY functions to find the > coordinates (in user coordinates to pass to rect) of the figure region > (or other regions). > > Probably something like: > grconvertX(c(0,1), from='nfc', to='user') > grconvertY(c(0,1), from='nfc', to='user')Hi Greg, Thanks, that's good to know. Cheers, Marius