[R] transforming output of grid.locator() to coordinates of a leaf viewport
Paul Murrell
p.murrell at auckland.ac.nz
Tue Jun 3 04:04:51 CEST 2008
Hi
Wittner, Ben, Ph.D. wrote:
> Hadley, In my application the leaf viewports will not overlap, but I guess that
> would not necessarily be the case for all applications. In any event, do you
> happen to know how to transform coordinates in the top-level viewport to
> coordinates in another viewport in the tree? Thanks. -Ben
current.transform() transforms from *inches* within the current viewport
to *inches* on the overall device. Sounds like you need the inverse
transform.
If you are in a position to be able to enumerate all of your leaf
viewports, then this may be a possible approach:
- for each leaf viewport, visit the viewport and record the
current.transform() for each leaf viewport. Also record the size of the
current viewport (in inches).
- capture a click on the device (current viewport should be ROOT) in
*inches*, then iterate through the leaf viewports to determine which one
was clicked in.
- to determine whether the click was within the viewport, use something
like the following function (and check whether both new locations are
positive and smaller than the size of the viewport (in inches)):
newloc <- function(loc, trans) {
temploc <- c(loc, 1) %*% trans
(temploc/temploc[3])[-3]
}
Here's a simple example:
# two "leaf" viewports
# (one on the left half of the device, one on the right)
grid.newpage()
pushViewport(viewport(x=0, width=.5, just="left", name="left"))
transLeft <- current.transform()
sizeLeft <- c(convertWidth(unit(1, "npc"), "inches", valueOnly=TRUE),
convertHeight(unit(1, "npc"), "inches", valueOnly=TRUE))
# Draw a rect for visual reference
grid.rect(gp=gpar(fill=hcl(240, 60, 80)))
upViewport()
pushViewport(viewport(x=.5, width=.5, just="left", name="right"))
sizeRight <- c(convertWidth(unit(1, "npc"), "inches", valueOnly=TRUE),
convertHeight(unit(1, "npc"), "inches", valueOnly=TRUE))
heightRight <- convertHeight(unit(1, "npc"), "inches", valueOnly=TRUE)
grid.rect(gp=gpar(fill=hcl(120, 60, 80)))
upViewport()
# Get a click
# (current viewport is the ROOT viewport)
click <- grid.locator(unit="inches")
# For each leaf viewport, calculate where the click was
leftClick <- newloc(unlist(click), solve(transLeft))
rightClick <- newloc(unlist(click), solve(transRight))
# Which one was it in ?
all(leftClick > 0 & leftClick < sizeLeft)
all(rightClick > 0 & rightClick < sizeRight)
Does that help ?
Paul
> ________________________________
>
> From: hadley wickham [mailto:h.wickham at gmail.com]
> Sent: Sun 6/1/2008 3:24 PM
> To: Wittner, Ben, Ph.D.
> Cc: r-help at stat.math.ethz.ch
> Subject: Re: [R] transforming output of grid.locator() to coordinates of a leaf
> viewport
>
>
>
> Ben,
>
> What if the click occurs over multiple viewports?
>
> Hadley
>
> On Mon, Jun 2, 2008 at 6:50 AM, Wittner, Ben, Ph.D.
> <Wittner.Ben at mgh.harvard.edu> wrote:
>> Short form:
>>
>> How do I transform the output of grid.locator() (or
>> grid.locator(unit='npc')) to the native (or npc) coordinates of a viewport
> other
>> than the top-level viewport?
>>
>> Thanks in advance. -Ben
>>
>> Long form:
>>
>> I would like the user to be able to click anywhere on the R
>> graphics window. I would then like to figure out which leaf viewport the user
>> clicked in and compute the native coordinates in that leaf viewport of the
>> user's click.
>>
>> I saw a 2005 response by Paul Murrell to a post by Gabor
>> Grothendieck roughly on this topic in which Paul suggested looking at
>> trellis.focus(). I've looked at trellis.focus() and trellis.clickFocus(), but
>> they don't appear to do what I want in that a) it would appear that my user
>> would have to click twice, once to specify which leaf viewport and then again
> to
>> specify which point in that viewport and b) trellis.clickFocus() appears to
> use
>> lots of information from the trellis package, which I'm not using.
>>
>> So I decided to try to figure out the native coordinates of the
>> click in each leaf viewport, to a) see whether the click is within the
> plotting
>> region for that viewport and b) use those coordinates to take the appropriate
>> action if it is. But I don't seem to be able to figure out how to translate
> from
>> the top-level viewport coordinates to those of a leaf viewport. I tried
>> interpreting the 3X3 matrix returned by current.transform() as an affine
>> transformation in the x,y plane in homogeneous coordinates, but could make no
>> sense of what I was getting.
>>
>> Thanks for any help. -Ben
>>
>>
>>
>>
>> The information transmitted in this electronic communica...{{dropped:16}}
>>
>> ______________________________________________
>> 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.
>>
>
>
>
> --
> http://had.co.nz/
>
>
>
> The information transmitted in this electronic communica...{{dropped:16}}
>
> ______________________________________________
> 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