[R] locator() via tcltk

Jean.Coursol@math.u-psud.fr Jean.Coursol at math.u-psud.fr
Sat Jun 4 11:54:36 CEST 2005


To illustrate (?) Professor Ripley comments, I send you an example (stolen in
various places...).

Note the tkwm.resizable(tt, 0, 0) directive that prevents the window rescaling
(if not,the coordinates will not be correct).

#
# Getting the mouse coords with TclTk
#

# Two possibilities: tkrplot package or Img library
# ========================================================
# A) USING the tkrplot package
#
# 1a) Opening an X11 device named "XImage" (current device)

     X11("XImage",width=600, height=600)

# 2a) Putting a contour...

     x <- 10*(1:nrow(volcano))
     y <- 10*(1:ncol(volcano))
     image(x, y, volcano, col = terrain.colors(100), axes = FALSE)
     contour(x, y, volcano, levels = seq(90, 200, by = 5),
             add = TRUE, col = "peru")
     axis(1, at = seq(100, 800, by = 100))
     axis(2, at = seq(100, 600, by = 100))
     box()
     title(main = "Maunga Whau Volcano", font.main = 4)

     # image dimensions (before "XImage" deletion)

     parPlotSize <- par('plt')
     usrCoords   <- par('usr')

# 3a) tkrplot loading (that load tcltk package)
#    The tcltk directive extended by tkrplot
#         image create Rplot truc
#    put the "XImage" image in the image Tcl objet named "truc"
#    and close "XImage"

     library(tkrplot)

     .Tcl("image create Rplot truc")

# ========================================================
# B) USING the Tcl Img library (for .jpg and .png)

# 1b) Opening a jpeg (or png) device

      jpeg("monimage.jpg",width=800, height=800)

# 2b)  = 2) + closing jpeg device

     x <- 10*(1:nrow(volcano))
     y <- 10*(1:ncol(volcano))
     image(x, y, volcano, col = terrain.colors(100), axes = FALSE)
     contour(x, y, volcano, levels = seq(90, 200, by = 5),
             add = TRUE, col = "peru")
     axis(1, at = seq(100, 800, by = 100))
     axis(2, at = seq(100, 600, by = 100))
     box()
     title(main = "Maunga Whau Volcano", font.main = 4)

     # image dimensions

     parPlotSize <- par('plt')
     usrCoords   <- par('usr')
     dev.off()

# 3b) Reading the "monimage" file in the Tcl objet named "truc"
#     and deleting the file

      library(tcltk)
      tclRequire('Img')  # to read a .jpg file
      truc <- tclVar()

      tkcmd("image","create","photo",truc,file="monimage.jpg")
      unlink("monimage.jpg")

# ========================================================
# COMMON STEPS for both possibilities

# 4) Opening the Tk window and putting the image inside

     tt <- tktoplevel()
     tkpack(ll <- tklabel(tt, image=truc), fill="both")
     tkwm.resizable(tt, 0, 0)             # non resizable window

# 5) Callback

     # Calculus of dimensions initial image/tk image

     width  <- as.numeric(tclvalue(tkwinfo("reqwidth",ll)))
     height <- as.numeric(tclvalue(tkwinfo("reqheight",ll)))

     xMin   <- parPlotSize[1] * width
     xRange <- (parPlotSize[2] - parPlotSize[1]) * width
     rangeX <- (usrCoords[2] - usrCoords[1])/xRange

     yMin   <- parPlotSize[3] * height
     yRange <- (parPlotSize[4] - parPlotSize[3]) * height
     rangeY <- (usrCoords[4] - usrCoords[3])/yRange

     OnLeftClick = function(x,y) {
       xClick <- as.numeric(x)
       yClick <- height - as.numeric(y)
       xPlotCoord <- usrCoords[1]+(xClick-xMin)*rangeX
       yPlotCoord <- usrCoords[3]+(yClick-yMin)*rangeY

       ##  AN ACTION ##
       print(c(xPlotCoord, yPlotCoord))
     }

tkbind(tt, "<Button-1>", OnLeftClick)                   # Action
tkbind(tt, "<Button-3>", function() tclvalue(done) = 1) # Exit

# 6) Loop waiting the events

done = tclVar(0)
tkwait.variable(done)
tkdestroy(tt)

###

-- 



Selon Prof Brian Ripley <ripley at stats.ox.ac.uk>:

> You have two asynchronous processes here: your R function will return,
> leaving a Tk widget up.  Duncan Murdoch's solution is to give you a
> function that will retrieve at some future stage the result of the last
> press (if any) of "Get coordinates" button.  Is that what you want?
>
> I think it is more likely you want to wait for the Tk interaction and then
> return the results, that is use a `modal' widget.  If so, take a look at
> the examples in src/library/tcltk/R/utils.R which are modal and return
> their results.
>
> On Fri, 3 Jun 2005, Sebastian Luque wrote:
>
> > Hello,
> >
> > I'm trying to write a function using tcltk to interactively modify a plot
> > and gather locator() data. I've read Peter's articles in Rnews, the help
> > pages in tcltk, http://bioinf.wehi.edu.au/~wettenhall/RTclTkExamples/,
> > plus a post in R-help sometime ago, but haven't found a solution.
> > The idea goes something like this:
> >
> > require(tcltk)
> > testplot <- function() {
> >  getcoords <- function(...) {
> >    locator(5)
> >  }
> >  x <- 1:1000
> >  y <- rnorm(1000)
> >  plot(x, y)
> >  base <- tktoplevel()
> >  loc.pts <- tkbutton(base, text = "Get coordinates", command = getcoords)
> >  quit.but <- tkbutton(base, text = "Quit",
> >                       command = function() tkdestroy(base))
> >  tkpack(loc.pts, quit.but)
> > }
> >
> > I'd like testplot to return the value from getcoords. The "Get
> > coordinates" button seems to be correctly calling getcoords, and locator
> > is doing its job, but I don't know how to store its value. Any help is
> > very much appreciated.
>
> --
> Brian D. Ripley,                  ripley at stats.ox.ac.uk
> Professor of Applied Statistics,  http://www.stats.ox.ac.uk/~ripley/
> University of Oxford,             Tel:  +44 1865 272861 (self)
> 1 South Parks Road,                     +44 1865 272866 (PA)
> Oxford OX1 3TG, UK                Fax:  +44 1865 272595
>
> ______________________________________________
> R-help at stat.math.ethz.ch mailing list
> https://stat.ethz.ch/mailman/listinfo/r-help
> PLEASE do read the posting guide! http://www.R-project.org/posting-guide.html
>




More information about the R-help mailing list