Coyote's Guide to IDL Programming

Positioning Images in IDL

New users of IDL are often confused by the difference in positioning graphics plots (see the Position Plots Programming Tip) and positioning images in the display window. Graphic plots are usually positioned with normalized coordiates. Images are almost always positioned with device (or pixel) coordinates. There is a one-to-one correspondence between a pixel on the display and a pixel in the image.

For example, to position an image with its lower-left corner at the XY location (65, 125) in device or pixel coordinates, you would type this:

   IDL> TV, image, 65, 125

Images don't care very much whether they fit into a window or not. (To be perfectly honest with you, images don't even think let alone have feelings. But I have found it easier to work with images if I treat them as though they had feelings.) In the IDL command above, for example, if your image was a 600-by-800 array and your display window was 400-by-600 pixels in size, your image would get clipped. The display window is not big enough to accomodate it.

This fact about images makes it difficult sometimes to position images in graphics windows, expecially windows that can be resized by the user. It also makes it difficult to work with images and graphics plots together. Fortunately, there is a way to work around these difficulties.

Positioning Images with Normalized Coordinates

Suppose for a moment that you weren't fastidious about preserving the aspect ratio of your image (i.e., its relative proportion of length to height). But what you wanted was for your image to always fill up the middle 80% of the display window. In terms of normalized coordinates (see the Position Plots Programming Tip for more information about this), you can say you would like its position to be given like this:

   IDL> position = [0.1, 0.1, 0.9, 0.9]

[Editor's Note: It turns out that a position such as shown above counter-intuitively takes up only 64% of the area of the window, not 80%. If you are the sort of person who likes his numbers exact, you will want to read this cogent explanation by Ed Vaughan of the bogus mathematics I used to arrive at this estimate).]

The question you want to ask yourself is, "How big does my image have to be to fill up this much space?" The answer, of course, depends upon the size of the graphics window. Luckily, you have that information at the tip of your fingertips, because the current visible area of the graphics display window is always given by the system variables !D.X_VSIZE and !D.Y_VSIZE. These system variables report their sizes in device or pixel coordinate units.

So, you want your image to be 80% of the graphics window size. In terms of the position variable above, you can write the desired X and Y sizes of your image in pixel units like this:

   IDL> xsize = (position(2) - position(0)) * !D.X_VSIZE
   IDL> ysize = (position(3) - position(1)) * !D.Y_VSIZE

You can also calculate where you would like the lower-left corner of your image to be placed in the window in pixel units like this:

   IDL> xstart = position(0) * !D.X_VSIZE
   IDL> ystart = position(1) * !D.Y_VSIZE

To display your image in the graphics window (of any size), you can simply type:

   IDL> TV, CONGRID(image, xsize, ysize), xstart, ystart

Sizing Images in PostScript Output

Unfortunately, images are not sized like this in PostScript output. PostScript devices are said to have scalable pixels. This means an image can be sized by the PostScript device itself. In practice, this is accomplished by using the XSIZE and YSIZE keywords of the TV command. For example, if you want the image above to fill 80% of the PostScript output window, the TV command above becomes:

   IDL> TV, xstart, ystart, XSIZE=xsize, YSIZE=ysize

For additional information on positioning and sizing images in PostScript, click here.

A Program for Displaying and Positioning Images

I've gotten around the problem of positioning images differently from other graphics and having to size images differently in PostScript by writing a general purpose image display program named cgImage. This program uses the POSITION keyword to locate images in the window. The call to cgImage looks like this:

   IDL> cgImage, image, POSITION=[0.1, 0.1, 0.9, 0.9]

I've found two major advantages to cgImage: (1) using the POSITION keyword makes it possible to use cgImage in conjuction with other IDL graphics routines in a natural way, and (2) cgImage makes it trivial to put my images into resizeable graphics windows and into PostScript windows, since the program displays images identically in both environments.

Moreover, cgImage can retain the aspect ratio of the image if that behaviour is required or desired. To do so, simply set the KEEP_ASPECT_RATIO keyword like this:

   IDL> cgImage, image, POSITION=[0.1, 0.1, 0.9, 0.9], /KEEP_ASPECT_RATIO

The cgImage program is in the Coyote Library. You will need to install the Coyote Library to use it.

[Return to IDL Programming Tips]