The PLplot Plotting Library: Programmer's Reference Manual
Prev | Chapter 3. Advanced Use of PLplot | Next

# Output Devices

PLplot supports a variety of output devices, via a set of device drivers. Each driver is required to emulate a small set of low-level graphics primitives such as initialization, line draw and page advance, as well as be completely independent of the PLplot package as a whole. Thus a driver may be very simple, as in the case of the many black and white file drivers (tektronix, etc.). More complicated and/or color systems require a bit more effort by the driver, with the most effort required by an output device with a graphical user interface, including menus for screen dumps, palette manipulation, and so forth. At present only the tk driver does the latter on Unix systems. At present we aren't pursuing a Macintosh development effort due to a lack of time and expertise, but will assist anyone wanting to volunteer for the job.

Note that if you always render to a PLplot metafile, you can always `plrender` them to new devices as they become available.

The list of available devices presented when starting PLplot (via `plstar`) is determined at compile time. When installing PLplot you may wish to exclude devices not available on your system in order to reduce screen clutter. To include a specified device, simply define the appropriate macro constant when building PLplot (see the installation instructions for your system).

The device drivers for PLplot terminal output at present are given in Table 3-1 while drivers for file output are given in Table 3-2. The driver for OS/2 PM is available separately. See the section on OS/2 in the Appendix for more details.

Table 3-1. PLplot Terminal Output Devices

Device | keyword | driver file
--- | --- | ---
X-Window Screen | xwin | xwin.c
Tcl/Tk widget | tk | tk.c
Linux console VGA | vga | linuxvga.c
Xterm Window | xterm | tek.c
Tektronix Terminal (4010) | tekt | tek.c
Tektronix Terminal (4105/4107) | tek4107t | tek.c
MS-Kermit emulator | mskermit | tek.c
Versaterm vt100/tek emulator | versaterm | tek.c
VLT vt100/tek emulator | vlt | tek.c
Conex vt320/tek emulator | conex | tek.c
DG300 Terminal | dg300 | dg300.c
NeXT display (unsupported) | nx | next.c
GNOME display | gnome | gnome.c
GNOME Canvas Widget / Display | gcw | gcw.c

Table 3-2. PLplot File Output Devices

Device | keyword | driver file
--- | --- | ---
PLplot Native Meta-File | plmeta | plmeta.c
Tektronix File (4010) | tekf | tek.c
Tektronix File (4105/4107) | tek4107f | tek.c
PostScript File (monochrome) | ps | ps.c
PostScript File (color) | psc | ps.c
XFig file | xfig | xfig.c
LaserJet IIp Bitmap File | ljiip | ljiip.c
LaserJet II Bitmap File (150 dpi) | ljii | ljii.c
HP 7470 Plotter File (HPGL Cartridge Small Plotter) | hp7470 | hpgl.c
HP 7580 Plotter File (Large Plotter) | hp7580 | hpgl.c
HP Laser Jet, HPGL file | lj_hpgl | hpgl.c
Impress File | imp | impress.c
Portable bitmap file | pbm | pbm.c
Null device | null | null.c
JPEG file | jpeg | gd.c
PNG file | png | gd.c
Computer Graphics Metafile | cgm | cgm.c

## Driver Functions

A dispatch table is used to direct function calls to whatever driver is chosen at run-time. Below are listed the names of each entry in the PLDispatchTable dispatch table struct defined in `plcore.h`. The entries specific to each device (defined in `drivers/*.c`) are typically named similarly but with "pl_" replaced by a string specific for that device (the logical order must be preserved, however). The dispatch table entries are :

- `pl_MenuStr`: Pointer to string that is printed in device menu.

- `pl_DevName`: A short device "name" for device selection by name.

- `pl_type`: 0 for file-oriented device, 1 for interactive (the null driver uses -1 here).

- `pl_init`: Initialize device. This routine may also prompt the user for certain device parameters or open a graphics file (see Notes). Called only once to set things up. Certain options such as familying and resolution (dots/mm) should be set up before calling this routine (note: some drivers ignore these).

- `pl_line`: Draws a line between two points.

- `pl_polyline`: Draws a polyline (no broken segments).

- `pl_eop`: Finishes out current page (see Notes).

- `pl_bop`: Set up for plotting on a new page. May also open a new a new graphics file (see Notes).

- `pl_tidy`: Tidy up. May close graphics file (see Notes).

- `pl_state`: Handle change in PLStream state (color, pen width, fill attribute, etc).

- `pl_esc`: Escape function for driver-specific commands.

Notes: Most devices allow multi-page plots to be stored in a single graphics file, in which case the graphics file should be opened in the pl_init() routine, closed in pl_tidy(), and page advances done by calling pl_eop and pl_bop() in sequence. If multi-page plots need to be stored in different files then pl_bop() should open the file and pl_eop() should close it. Do NOT open files in both pl_init() and pl_bop() or close files in both pl_eop() and pl_tidy(). It is recommended that when adding new functions to only a certain driver, the escape function be used. Otherwise it is necessary to add a null routine to all the other drivers to handle the new function.

## PLplot Metafiles and Plrender

The PLplot metafile is a way to store and transport your graphical data for rendering at a later time or on a different system. A PLplot metafile is in binary format in order to speed access and keep storage costs reasonable. All data is stored in device-independent format (written as a stream of bytes); the resulting file is about as portable as a tektronix vector graphics file and only slightly larger.

Each PLplot metafile begins with a header string that identifies it as such, as well as the version number of the format since this may change in time. The utility for rendering the metafile, `plrender`, verifies that the input file is indeed a valid PLplot metafile, and that it "understands" the format the metafile is written in. `plrender` is part of the PLplot package and should be built at the time of building PLplot, and then put into your search path. It is capable of high speed rendering of the graphics file, especially if the output device can accept commands at a high rate (e.g. X windows).

The commands as written by the metafile driver at present are as follows:

- `INITIALIZE`

- `CLOSE`

- `SWITCH_TO_TEXT`

- `SWITCH_TO_GRAPH`

- `CLEAR`

- `PAGE`

- `NEW_COLOR`

- `NEW_WIDTH`

- `LINE`

- `LINETO`

- `ESCAPE`

- `ADVANCE`

Each command is written as a single byte, possibly followed by additional data bytes. The `NEW_COLOR` and `NEW_WIDTH` commands each write 2 data bytes, the `LINETO` command writes 4 data bytes, and the `LINE` command writes 8 data bytes. The most common instruction in the typical metafile will be the `LINETO` command, which draws a continuation of the previous line to the given point. This data encoding is not quite as efficient as the tektronix format, which uses 4 bytes instead of 5 here (1 command `+` 4 data), however the PLplot encoding is far simpler to implement and more robust. The `ESCAPE` function writes a second command character (opcode) followed by an arbitrary number of data bytes depending on the value of the opcode. Note that any data written must be in device independent form to maintain the transportability of the metafile so floating point numbers are not allowed.

The short usage message for `plrender` is printed if one inputs insufficient or invalid arguments, and is as follows:

    % plrender

    No filename specified.

    Usage:
            plrender [options] [files]

    plrender options:
        [-v] [-i name] [-b number] [-e number] [-p page]

    PLplot options:
        [-h] [-v] [-verbose] [-debug] [-dev name] [-o name] [-display name]
        [-px number] [-py number] [-geometry geom] [-wplt xl,yl,xr,yr]
        [-mar margin] [-a aspect] [-jx justx] [-jy justy] [-ori orient]
        [-freeaspect] [-width width] [-bg color] [-ncol0 n] [-ncol1 n] [-fam]
        [-fsiz size] [-fbeg number] [-finc number] [-fflen length] [-nopixmap]
        [-db] [-np] [-server_name name] [-server_host name] [-server_port name]
        [-user name]

    Type plrender -h for a full description.

The longer usage message goes into more detail, and is as follows:

    % plrender -h

    Usage:
            plrender [options] [files]

    plrender options:
        -v                   Print out the plrender version number
        -i name              Input filename
        -b number            Beginning page number
        -e number            End page number
        -p page              Plot given page only

    If the "-i" flag is omitted, unrecognized input will assumed to be filename
    parameters.  Specifying "-" for the input or output filename means use stdin
    or stdout, respectively.  See the manual for more detail.

    PLplot options:
        -h                   Print out this message
        -v                   Print out the PLplot library version number
        -verbose             Be more verbose than usual
        -debug               Print debugging info (implies -verbose)
        -dev name            Output device name
        -o name              Output filename
        -display name        X server to contact
        -px number           Plots per page in x
        -py number           Plots per page in y
        -geometry geom       Window size, in pixels (e.g. -geometry 400x300)
        -wplt xl,yl,xr,yr    Relative coordinates [0-1] of window into plot
        -mar margin          Margin space in relative coordinates (0 to 0.5, def 0)
        -a aspect            Page aspect ratio (def: same as output device)
        -jx justx            Page justification in x (-0.5 to 0.5, def 0)
        -jy justy            Page justification in y (-0.5 to 0.5, def 0)
        -ori orient          Plot orientation (0,2=landscape, 1,3=portrait)
        -freeaspect          Do not preserve aspect ratio on orientation swaps
        -portrait            Sets portrait mode (both orientation and aspect ratio)
        -width width         Sets pen width (1 <= width <= 10)
        -bg color            Background color (0=black, FFFFFF=white)
        -ncol0 n             Number of colors to allocate in cmap 0 (upper bound)
        -ncol1 n             Number of colors to allocate in cmap 1 (upper bound)
        -fam                 Create a family of output files
        -fsiz size[kKmMgG]   Output family file size in MB (e.g. -fsiz 0.5G, def MB)
        -fbeg number         First family member number on output
        -finc number         Increment between family members
        -fflen length        Family member number minimum field width
        -nopixmap            Don't use pixmaps in X-based drivers
        -db                  Double buffer X window output
        -np                  No pause between pages
        -server_name name    Main window name of PLplot server (tk driver)
        -dpi dpi             Resolution, in dots per inch (e.g. -dpi 360x360)
        -compression num     Sets compression level in supporting devices
        -drvopt option[=value][,option[=value]]* Driver specific options

The options are generally self explanatory (family files are explained in the Section called Family File Output). Most of these options have default values, and for those that don't `plrender` will prompt the user. The `-px` and `-py` options are not so useful at present, because everything is scaled down by the specified factor --- resulting in labels that are too small (future versions of `plrender` might allow changing the label size as well).

Additional options may be added in future releases.

## Family File Output

When sending PLplot to a file, the user has the option of generating a "family" of output files for most output file drivers. This can be valuable when generating a large amount of output, so as to not strain network or printer facilities by processing extremely large single files. Each family member file can be treated as a completely independent file. In addition, `plrender` has the ability to process a set of family member files as a single logical file.

To create a family file, one must simply call `plsfam` with the familying flag `fam` set to 1, and the desired maximum member size (in bytes) in `bmax`. `plsfam` also allows you to set the current family file number. If the current output driver does not support familying, there will be no effect. This call must be made before calling `plstar` or `plstart`.

If familying is enabled, the name given for the output file (on the command line, in response to the `plstar` prompt, as a `plstart` argument, or as the result of a call to `plsfnam`) becomes the name template for the family. Thus, if you request a plmeta output file with name `test-%n.plm`, the files actually created will be `test-1.plm`, `test-2.plm`, and so on, where `%n` indicates where the member number is replaced. If there is no `%n`, then the output file becomes the stem name and the created files will be like `test.plm.1`, `test.plm.2`, and so on. A new file is automatically started once the byte limit for the current file is passed, but not until the next page break. One may insure a new file at every page break by making the byte limit small enough. Alternatively, if the byte limit is large you can still insure a new file is automatically started after a page break if you precede the call to `pleop` with a call to `plfamadv`.

The `plgfam` routine can be used from within the user program to find out more about the graphics file being written. In particular, by periodically checking the number of the member file currently being written to, one can detect when a new member file is started. This information might be used in various ways; for example you could spawn a process to automatically plrender each metafile after it is closed (perhaps during a long simulation run) and send it off to be printed.

`plrender` has several options for dealing with family files. It can process a single member file (`plrender` `test.plm.1`) or the entire family if given only the stem name (`plrender` `test.plm`) It can also create family files on output, rendering to any device that supports familying, including another metafile if desired. The size of member files in this case is input through the argument list, and defaults to 1MB if unspecified (this may be changed during the PLplot installation, however). `plrender` can also create a single output file from a familied input metafile.

## Interactive Output Devices

Here we shall discuss briefly some of the more common interactive output devices.

Many popular terminals or terminal emulators at present have a facility for switching between text and graphics "screens". This includes the xterm emulator under X-windows, vt100's with Retrographics, and numerous emulators for microcomputers which have a dual vt100/tek4010 emulation capability. On these devices, it is possible to switch between the text and graphics screens by surrounding your PLplot calls by calls to `plgra` and `pltext`. This will allow your diagnostic and informational code output to not interfere with your graphical output.

At present, only the xterm driver supports switching between text and graphics screens. The escape sequences as sent by the xterm driver are fairly standard, however, and have worked correctly on most other popular vt100/tek4010 emulators we've tried.

When using the xterm driver, hitting a RETURN will advance and clear the page. If indeed running from an xterm, you may resize, move, cover and uncover the window. The behavior of the X-window driver is quite different, however. First, it is much faster, as there is no tty-like handshaking going on. Second, a mouse click is used to advance and clear the page, rather than a RETURN.

On a tektronix 4014 compatible device, you may preview tektronix output files via the `pltek` utility. `pltek` will let you step through the file interactively, skipping backward or forward if desired. The help message for `pltek` is as follows:

    % pltek
    Usage: pltek filename
    At the prompt, the following replies are recognized:
       h,?    Give this help message.
        q     Quit program.
       <n>    Go to the specified page number.
       -<n>   Go back <n> pages.
       +<n>   Go forward <n> pages.
     <Return> Go to the next page.

The output device is switched to text mode before the prompt is given, which causes the prompt to go to the vt102 window under xterm and most vt100/tek4010 emulators.

## Specifying the Output Device

The main initialization routine for PLplot is `plinit`, which sets up all internal data structures necessary for plotting and initializes the output device driver. The output device can be a terminal, disk file, window system, pipe, or socket. If the output device has not already been specified when `plinit` is called, a list of valid output devices is given and the user is prompted for a choice. For example:

    % x01c

    Plotting Options:
     < 1> xwin       X-Window (Xlib)
     < 2> tk         Tcl/TK Window
     < 3> xterm      Xterm Window
     < 4> tekt       Tektronix Terminal (4010)
     < 5> tek4107t   Tektronix Terminal (4105/4107)
     < 6> mskermit   MS-Kermit emulator
     < 7> versaterm  Versaterm vt100/tek emulator
     < 8> vlt        VLT vt100/tek emulator
     < 9> plmeta     PLPLOT Native Meta-File
     <10> tekf       Tektronix File (4010)
     <11> tek4107f   Tektronix File (4105/4107)
     <12> ps         PostScript File (monochrome)
     <13> psc        PostScript File (color)
     <14> xfig       Xfig file
     <15> ljiip      LaserJet IIp/deskjet compressed graphics
     <16> ljii       LaserJet II Bitmap File (150 dpi)
     <17> null       Null device

    Enter device number or keyword:

Either the device number or a device keyword is accepted. Specifying the device by keyword is preferable in aliases or scripts since the device number is dependent on the install procedure (the installer can choose which device drivers to include). The device can be specified prior to the call to `plinit` by:

- A call to `plsdev`.

- The `-dev` `device` command line argument, if the program's command line arguments are being passed to the PLplot function `plparseopts`.

Additional startup routines `plstar` and `plstart` are available but these are simply front-ends to `plinit`, and should be avoided. It is preferable to call `plinit` directly, along with the appropriate setup calls, for the greater amount of control this provides (see the example programs for more info).

Before `plinit` is called, you may modify the number of subpages the output device is divided into via a call to `plssub`. Subpages are useful for placing several graphs on a page, but all subpages are constrained to be of the same size. For greater flexibility, viewports can be used (see the Section called Defining the Viewport for more info on viewports). The routine `pladv` is used to advance to a particular subpage or to the next subpage. The screen is cleared (or a new piece of paper loaded) if a new subpage is requested when there are no subpages left on the current page. When a page is divided into subpages, the default character, symbol and tick sizes are scaled inversely as the square root of the number of subpages in the vertical direction. This is designed to improve readability of plot labels as the plot size shrinks.

PLplot has the ability to write to multiple output streams. An output stream corresponds to a single logical device to which one plots independent of all other streams. The function `plsstrm` is used to switch between streams -- you may only write to one output stream at a time. At present, an output stream is not limited by the type of device, however, it may not be wise to attempt opening two terminal devices. An example usage for the creation of multiple streams is as follows:

    #include "plplot.h"

    main()
    {
        int nx = 2, ny = 2;

        plssub(nx, ny);
        plsdev("xwin");
        plinit();

        <plots for stream 0>

        plsstrm(1);
        plssub(nx, ny);
        plsdev("plmeta");
        plsfnam("tst.plm");
        plinit();

        <plots for stream 1>

        plsstrm(0);

        <plots for stream 0>

and so on, for sending output simultaneously to an X-window and a metafile. The default stream corresponds to stream number zero. At present, the majority of output drivers can only be used by a single stream (exceptions include the metafile driver and X-window driver). Also see example program 14 (note: only the C version is available, although it can be done equally well from Fortran).

At the end of a plotting program, it is important to close the plotting device by calling `plend`. This flushes any internal buffers and frees any memory that may have been allocated, for all open output streams. You may call `plend1` to close the plotting device for the current output stream only. Note that if PLplot is initialized more than once during a program to change the output device, an automatic call to `plend1` is made before the new device is opened for the given stream.

Prev | Home | Next
Advanced Use of PLplot | Up | Adding FreeType Library Support to Bitmap Drivers