Inserting R Graphics in Tk

Luke Tierney
School of Statistics
University of Minnesota

2002/05/01

Introduction

For prototyping GUI issues it is useful to be able to insert R graphics in a GUI widget. This note presents one quick and (very) dirty way of doing it for Tk, with some discussion that may be relevant for other packages. The implementation is available as a source package and and as a Windows binary package. (The Windows library may not be built quite right.)

Just for fun, a window dump of tkpersp is available.

This is intended only as a prototyping device, an existence proof of sorts. No guarantees of stability...

Strategy

The first issue is what kind of Tk entity the R graphic should be. There are two choices: a widget or an image. Adding a new image type seems to require less programming, so I have taken that route.

Next is the question of how to get R graphics output into the image. Some choices:

Windows already provides a metafile device that can be used to draw to the clipboard. The only wrinkle, other than trashing the clipboard, is that the way things are set up the device has to be closed to get the metafile. This is the way Windows metafiles work, and I think MacOS picture objects do too. To keep the device open would require closing the graphics context, opening a new one, and seeding it with the metafile. This is possible but would require modifying the windows driver. Since what we have is workable, for now I decided to go without driver modification and live with the idea that the device is closed by extracting its image.

In X11, the PNG and JPEG devices are already using pixmaps to hold their output and using XGetImage to access the pixmap contents. A small modification, which I have added to the R sources, allows the X11 driver to be set up as type XImage with a call like

X11("XImage", ...)
The driver just draws to the pixmap; no files are created. A function

<R_GetX11Image declaration>=
Rboolean R_GetX11Image(int d, XImage **pximage, int *pwidth, int *pheight)
Defines R_GetX11Image (links are to index).

is used to get an image of the current pixmap. This function can also be used with X11 or PNG devices; it does not close the device.

Performance of this approach on X11 seems adequate; on windows it is OK for the simple example but not very good for tkpersp, at least on my system. But it should do for prototyping purposes, which is all it is intended for.

On the Windows version for some reason when run with Rgui the R window comes to the front each time you create a Tk image, probably something with the device being closed.

Interface

Higher Level

The higher level interface is in the tkrplot package. It consists of the functions

<higher level functions>=
tkrplot(parent, fun)
tkrreplot(lab, fun = lab$fun)
tkpersp(...)

The function tkrplot creates and returns a Tk label widget containing a Tk image of type Rplot. For now the size is hard-wired. The plot is created by calling fun with a special device used create the image.

The function tkrreplot calls fun to place a new plot in the Rplot widget lab.

tkpersp is called like persp but produces a plot in which some of the parameters of persp are controlled graphically.

Low Level

The Tk side implements a new image type, Rplot. Creating an image of this type with
image create Rplot ?name?
extracts the image for the current device as a metafile, via the clipboard, or as an XImage and closes the device. The device must be of the appropriate type---a clipboard metafile device on Windows or an XImage device on X11.

Implementation

The implementation of the image can be based on the Img image format extension library

[BibTeX bibliography]

Indices

Chunks

Identifiers