## This script is a supplement to 'Conditional Visualization for Statistical ## Models: an Introduction to the condvis Package in R'. This is an example of ## interacting with two R plots, propagating the changes to the other plot as ## required. This currently seems to work only in Windows. Run the whole script. ## Function to create plot and return object storing ## device number, usr and mar/ myplot <- function (pch) { plot(0, 0, col = NULL, pch = pch) structure(list(device = dev.cur(), usr = par()$usr, mar = par()$mar, pch = pch), class = "myplot") } ## Update method for plot object: switches to the ## correct device, sets usr and mar, then plots ## a point given by 'x' and 'y'. update.myplot <- function (object, x, y, col) { dev.set(object$device) par(usr = object$usr) par(mar = object$mar) points(x, y, pch = object$pch, col = col) } ## Function to create an event handler function to react ## to mouseclicks, which takes the xy coordinates of the ## mouseclick, interprets them to the correct user coordinates, ## and draws a point to both devices via 'update'. mouseclick <- function (object, col) { function(buttons, x, y) { dev.set(object$device) par(usr = object$usr) par(mar = object$mar) xnew <- grconvertX(x, "ndc", "user") ynew <- grconvertY(y, "ndc", "user") update(o1, x = xnew, y = ynew, col = col) update(o2, x = xnew, y = ynew, col = col) } } ## Function to create an event handler function to react ## to keystrokes: just providing a way to end the ## interactive session by pressing 'q'. keystroke <- function () { function (key) { if (identical(key, "q")) { cat("\nInteractive session ended.\n") return(invisible(1)) } } } ## Open a suitable graphics device. if (identical(version$os, "linux-gnu")) { x11(type = "Xlib") } else { x11() } ## Create plot, save resulting object and set up the ## event listener. o1 <- myplot(1) title(main = "points clicked here are blue") setGraphicsEventHandlers( onMouseDown = mouseclick(o1, "blue"), onKeybd = keystroke()) ## Open a second suitable graphics device. if (identical(version$os, "linux-gnu")) { x11(type = "Xlib") } else { x11() } ## Create another plot with different ranges, save resulting ## object and set up a separate event listener. o2 <- myplot(2) title(main = "points clicked here are red") setGraphicsEventHandlers( onMouseDown = mouseclick(o2, "red"), onKeybd = keystroke()) ## Listen for mouseclicks. getGraphicsEvent() ## Click around the plot area on EITHER device, the point ## is plotted on each device at the same coordinates with ## colour to show where the click originated.