ploticus: frequently asked questions

## Frequently Asked Questions | Welcome Gallery Handbook |
| Manual page for Frequently_Asked_Questions(PL)

## FAQ

Frequently asked questions about ploticus. If you don't see it here, just ask (`steve@sgpr.net`).``

Where can I get ploticus?``

  www.sgpr.net or the central Europe mirror site.``

Where can I report problems or get help?

  How to submit a problem report

What computing environments are supported?

  Definitely: Solaris 2, Linux, AIX, FreeBSD, Irix, HP-UX, HP3000 MP/ix, Digital Unix 4.0, Windows/NT with Cygwin, Windows/NT with DJGPP.`` Probably: Other modern Unix-like platforms.``

How many users are there?

  Most users who have written in are present on the current or earlier user feedback pages.``

What is the easiest way to get started?

  Download the software. Then, see of one of the available prefabs is close to what you want.`` When a prefab is used, all that needs to be specified by the user are several key parameters.

  For more flexibility and power, you can develop your own ploticus scripts

Can you add a search engine to the web site? It is difficult to sift through all the examples and handbook sections.

  For now, I would recommend downloading the entire doc node including gallery examples and handbook. Then you can search and peruse all of the material locally using "grep" or however you prefer to do it.``

Can I use ploticus as part of a commercial package or service?

  As of version 1.41 ploticus is covered under the GNU General Public License.`` The GPL does not allow ploticus code to be used in proprietary software that is to be distributed to others (please see the copyright page for details, or contact me at `steve@sgpr.net` if questions).``

  For cases where standalone ploticus executables are included as a reporting utility within a larger specialized system, I am comfortable in considering ploticus as an ancillary part of such a package, and interpret the GPL section 2 as requiring that GPL be attached only to ploticus, and not the whole package. For this to be allowed, the rest of your product must be considered an independent and seperate work in its own right, the executables must be derived from unmodified standard ploticus source code (except as needed to get it to compile and work properly), and you must include a prominent statement to the effect that graphs are produced using the Ploticus data display program (c) 2001 Steve Grubb and that the Ploticus program is freely downloadable at www.sgpr.net.

I have compiled ploticus on platform XYZ. Should I send you the binaries?.``

  For a while I was receiving binaries for various platforms and posting them to the web site. However because of the work involved and the tendency for this to slip out of date, I would now prefer to just add a URL link to the binary on your site.``

Ploticus wants to put its temp files on /usr/tmp, but my system does not have /usr/tmp.

  As of version 1.38, you can specify a temp directory in the ploticus config file.`` You can, of course, also directly modify the default temp directory in preliminaries.c.``

I need a customized plot. If I am coding a script from scratch, what is the bare minimum of code I need?

  If starting from scratch, just remember that in order to do a plot you need data (#proc getdata) a plotting area (#proc areadef) with the X and Y ranges defined, and a plotting proc such as #proc bars. The plotting proc usually requires that a data field be given. Other parameters will use defaults.``

Why would I want to use ploticus rather than a MainStream desktop spreadsheet / charting package / slides package to create graphs?

  Ploticus might be your choice for stylistic reasons or just because it suits the problem or application.``

  You can also use Ploticus with other document/media production tools (e.g.`` generate data displays using ploticus then import PNG into PowerPoint, Word, etc.)

How does ploticus compare with other freeware plotting/charting packages?

  Here is a list of some other plotting packages (thanks to Arthur Ferruzzi).``

  In general, ploticus is good at making graphs like you would see in newspapers and news magazines, business publications, journals for medical and social sciences, and so on.``

  Ploticus is not a function or mathematical plotting package like gnuplot, nor would it be a good choice for applications where mathematical formulas or scientific notations are to be rendered as an integral part of the data display.``

  Ploticus is also not intended as a "marketing" graphics package.`` Its goal is to display data crisply without extra decoration and distracting "dingbats" that cloud the picture.`` Thus there is little support for 3-D effects, gradient backgrounds, and so on.

Are there any licensing restraints related to GIF generation with ploticus ?

  Because of the confusion surrounding the licensing mess, PNG is recommended rather than GIF ( more info ), and GIF support may be dropped at some future point in time.``

  However, please note the following: Ploticus does not read GIF files.`` Ploticus writes run-length-encoded (RLE) GIF files.`` Our understanding is that these RLE GIF files do not use patented LZW compression ( more info ).

What does ploticus include?

  Two programs, pl and pltab.`` If you download the binaries, there is no 'install' procedure. If you download the sources, the build is uncomplicated and should work fine. Then, just move the executables (pl, pltab, plpng, and pltabpng) to an accessible bin and you're all set.``

What does the pl program do?

  pl generates plots and graphs, as specified in a script . Most of the gallery examples were generated using pl.`` It generates data displays using a page layout model, which means that you need to specify exactly where on the "page" each plot will be placed.`` To use it, you would type a command such as this:
  pl -gif lineplot1.htm

What does the pltab program do?

  Pltab is an occasionally useful utility that takes ordinary ascii tables and lists such as program output and creates presentable tables by setting them in a nice font, and often adding embellishments such as rulings, shading, font changes, and embedded plots and graphs.`` Pltab is a productive way to get plain program output (tables and lists) into presentable form; no formatting codes or massaging of output is required.`` Pltab automatically overflows onto multiple pages and thus is useful in creating multi-page graphical case displays such as this . To use pltab you would type a command such as this:
  pltab table.out | lp

The name 'pl' conflicts with that of my prolog interpreter. Also the file name extension .pl is easy to confuse with 'perl'.

  Please feel free to rename the executables as appropriate for your system.`` Ploticus is "aware" of the following file name extensions that may be used for ploticus scripts: .pl .p .pls .htm .html. "Aware" means that if no output file name is specified (-o) ploticus can strip off the extension and tack on .png, .gif, .eps, etc. to make the output file name. Otherwise out.png (etc.) will be used as a fallback.``

Can I invoke ploticus from C/C++/Perl/etc?

  Currently the best way is to invoke pl or pltab using `system()` or something similar.``

How can I use ploticus from a CGI?

  As of version 2.00 you can invoke pl directly as a CGI program.`` Here's how to do it.`` Another way to go about it is to 1) generate a unique temp file name; 2) invoke ploticus via shell or system() and build a PNG or GIF file using the unique name; 3) reference that file in an <IMG> tag; 4) clean up temp PNG / GIF files regularly using a find command run by cron.``

When I use ploticus from the command line it works fine, but when invoked from my perl script it misbehaves..

  Sorry, I don't use perl, and can't be of any help on perl implementation issues.``

I have a program that generates a stream of X Y coordinates to create a special display. How can I display my results via Ploticus?

  Proc Drawcommands may be used, assuming you can adjust or post-process your program's output to conform to the Drawcommands command set.``

Do I have to learn the script language?

  You do not, if you can get by with just the prefabs . For more customization and flexibility you can write scripts and then you do need to become familiar with the script language.`` Fortunately, it is a goal-driven specifications language rather than a purely procedural one. As with many tools of this type, the best way to operate may be to copy an existing script and modify it to suit.`` The web-based handbook may be navigated quickly to find the names and uses of the various attributes.`` And, as mentioned above, if you use Ploticus much you might benefit from downloading the entire docs/examples node for easier searching and perusal.``

What graphics file formats can be created?

  You can create PNG or GIF images (typically used in web pages and other software applications), paginated PostScript files that can be printed, and EPS files (for printing or import into other document).`` You can also use it interactively on an X11 display.`` As of version 2.00 you can optionally link against your own copy of the GD library to get JPEG and WBMP.``

What plot data formats are accepted?

  Ordinary ascii files, where fields are either white space delimited, tab delimited or comma delimited. (The latter is sometimes called spreadsheet format, or .csv.) See data formats .``

  Most plotting operations are done on data fields.`` For example, you might do a bargraph on the values in field 3 of the data set.`` If your data are not organized that way, you can get data into a usable form using proc transform after the data are read.``

Why isn't it interactive?

  The main thrust has been to develop an engine that can produce graphics non-interactively, so that it can be run in an automated, unattended way.``

Are any statistical capabilities included?

  There is a built-in facility (proc tabulate) for computing frequency distributions. Means, medians, quartiles, standard deviations, etc. may be computed using proc rangebar. Proc curvefit can compute linear regression curve and Pearson correlation coefficient r.``

How can I render a proper less-than-or-equal-to symbol, Portugese characters, or other special symbols?

  This is now described here

I would like dates to use the German month abbreviations rather than the English.

  Non-english month abbreviations, etc. may be specified in a ploticus config file For example, see plconfig.spanish or plconfig.russian

Is there any way to get thousands separators so that large numbers are more readable e.g. 3,024,582? Also, I would prefer European style display of numbers, e.g. comma used as the decimal point, and period (.) used as the thousands separator.

  You can add a `numbernotation` entry into your ploticus config file to do either of these things (as of version 1.34).``

Is ploticus Y2K compliant?

  As of 9/00 there have been no problems reported. Of course, as always, correctness of individual results is the user's responsibility.``

What about large data sets?

  The capacities are fairly large (see program limits ). If your data set is too large, you may be able to use the `select` or `filter` attributes of proc getdata to pair down the size.`` `select` will select only certain records; `filter` may be used to keep only certain fields.``

Can I import the graphs into PowerPoint?

  Yes. PNG and GIF files may be inserted as pictures with PowerPoint.`` EPS files may be used with PowerPoint if the result will be rendered on a PostScript film imager.``

How can I view PNG or GIF files that I generate?

  You can view them with a locally-running web browser if you use a URL beginning with `file:///`, for example, `file:///export/home/steve/plot.gif` (note that there are three slashes, two for the URL syntax and one representing the root of the file system). You can also use an image viewing utility such as the publicly available xv package to view images locally.`` You can have ploticus invoke xv automatically to display your results using `-viewer xv` on the command line.``

  Note that old versions of browsers and image viewing tools may not support PNG.`` Here's a list of PNG viewers

How can I preview PostScript files that I generate?

  Use a PostScript previewing tool such as the publicly available ghostview package.`` You can have ploticus invoke gv automatically to display your results using `-viewer gv` on the command line.``

How can I enlarge or reduce my results?

  Use the -scale command line option.``

How can I make thumbnails?

  Just use a small scale factor, such as -scale 0.3.`` Very small text is rendered as lines automatically.``

How can I crop my results?

  Use one of the -crop, -croprel or -tightcrop command line options.``

-tightcrop is close to what I want but it is cropping too closely on one side.

  Try -croprel.``

I am trying to make a fairly large GIF file (12" wide by 4" high). The rightmost portions of the result are cut off.`` Is this a bug?

  It is not really a bug but not quite ideal in the way that it is handled.. The default output size is 8" x 8". If doing X11, PNG or GIF and your desired output exceeds either of these dimensions you should specify -pagesize on the command line, or pagesize in proc page, and give a big enough area to fit the entire result.``

Why is garbage being displayed at the end of my title?

  Attributes that are multi-line need to be terminated with a blank line. Perhaps the blank line was left out.``

I have changed an attribute value but nothing happens.

  If the attribute in question follows a multi-line attribute, you may have forgotten to terminate the multi-line attribute with a blank line.``

Is there any way for a single-line attribute such as proc getdata's 'fieldnames' to be expressed in multiple lines?

  Not currently. Only "multiline text" attributes may occupy multiple lines, and they must be terminated by a blank line.`` All other attributes must be contained within a single line of text.``

Something in my script does not seem to be working. See a fragment below....

       #proc getdata
       file: myfile.dat

       #if @NRECORDS = 0
         #exit
       #endif

       #proc bars..
         ..etc..

  ``

....... I know that my datafile indeed has many records of data in it, however, the script always exits without plotting any bars.

  The problem here is a nuance/glitch and has to do with the way that ploticus scripts are parsed.`` Variables, such as NRECORDS in your case, that are set within a proc do not become available to the script until the proc is finished. Procs are delineated by #proc statements. Thus, what happened is that ploticus didn't realize that you were finished with your proc getdata when the #if came along, and at that time NRECORDS was still zero.``

  To solve this, insert a `#proc endproc` statement immediately before the #if statement.`` It should be used in any situation where an #if or #set statement will use variables set by the previous proc.`` #proc endproc is really just a do-nothing marker and does not need to be used routinely all the time. I still trip up on this one occasionally -SG

What are #clone and #saveas and how do they work?

  #clone and #saveas are used when doing several similar plots, such as a set of four bar graphs that have the same style. #saveas saves the attribute settings for one proc invocation. #clone uses a set of attribute settings that was saved earlier.`` An example is volunteers See also the script syntax description .``

I have a graph where I set up the plotting area with procs areadef, yaxis, and two separate invocations of proc xaxis. I want to replicate this plotting area several times. How do I clone the plotting area?

  You need to use #saveas within every proc that is involved (with different instance names), and then use #clone all of the procs.`` There is no way to clone a set of procs together in one operation.``

Can I have 2 separate scatter plots on the same plot area? With 2 separate data sets, i.e. not col1 = x, col2 = y, col3 = other-y, but "these coord pairs are one kind of scatter dot, and this other completely unrelated set are a different kind of scatter dot."

  Yes, you do this by:

       	#proc areadef
        	...

       	#proc getdata
       	file: data1

       	#proc scatterplot
        	...

       	#proc getdata
       	file: data2

       	#proc scatterplot
       	.. etc..

  The first areadef stays in effect until a new areadef is specified, thus any number of plots may be rendered in the area.``

Can I make a Y axis on the right edge of the plot rather than the left?

  Yes, see gallery example sa12 .``

Is it possible to overlay two coordinate systems on one plot?

  Yes, see gallery example sa13 which overlays Celsius and Fahrenheit.``

How can I have grid lines in orange every 0.1 unit, and then grid lines in black every 1.0 unit?

  Invoke #proc axis twice and overlay the two, to get more complex systems of grids, tics, and stubs. See example sa14 which does this.``

An axis labelling question: my xrange goes from 0.5 to 12. When I do stubs of "increment 1" they are drawn at 0.5, 1.5, 2.5, etc.. I want them to be at 1.0, 2.0, etc.

  Stub placement begins by default at the minima. To override this, the stubrange attribute can be used. For your case, it would be: `stubrange: 1.0`

Is there a way to do a broken Y axis?

  Yes, although broken axes cannot be done in an automated way.`` See gallery example brokenaxis and the man page for proc breakaxis

I am trying to do a plot where the X axis is dates expressed in quarter years (quarters), to show quarterly results. It is not coming out right.

  It is a little bit tricky because data in quarter notation is converted to a full date midpoint, so the X range needs to be expressed in a full date notation, then you change units to quarter notation. See the example quarters which illustrates.``

Is there any way to make an axis progress from a large value to a small value?

  Yes, although it is not entirely straighforward.`` See gallery example hbars4 Ploticus is limited by its implementation in that it can only produce axes that run from a low value to a higher value. In order to "fool" it into going from high to low, you must reverse the sign of your data values (proc getdata's filter attribute might be used to do this), and define your plotting range accordingly.`` Then you can use proc axis's reversesign option (introduced in version 1.3) to present the axis stubs.``

How can I make the Y axis of my plotting area automatically scaled to my data?

  Use proc areadef's `yautorange` attribute.`` This takes several sub-attributes, the most important of which is `datafield=`n.``

I am trying to set up an automated system that will generate a reasonable plot for any reasonable numeric data that gets thrown at it. Areadef's xautorange and yautorange get me part of the way there, but it appears I still need to specify the stub increment and "autorange nearest" attributes manually, which has me stymied.

  As of version 1.39, you can get a reasonable default stub increment for numeric data by stating: `stubs: inc` or `stubs: inc 0`.`` Also as of version 1.39, you can get a reasonable default "autorange nearest" for numeric data by simply omitting the word "nearest" (the default used to be to go to the exact minima and maxima; to do this you now need to state "nearest=exact").``

I want to plot my data in log-log scale with an x-range from 0.1 to 100 and a yrange from 1 to 1000.`` The trouble is that ploticus uses fixed tic increments by default.`` This makes the tics pile together at the upper limits. Is there an easy way to produce tics with variable values, for example, the increment for the range from 1 to 10 is 1, from 10 to 100 is 10, etc.?

  You could use proc axis' `selflocatingstubs` attribute, which allows you to place the tics and/or stubs whereever you wish. However it is not automatic. An example is loglog

I have large files containing dates and times of events.`` I would like to plot them as histograms across time.`` Some events happen concurrently (at the same time).`` Thus I need to run a frequency distribution on the date and time, however, proc tabulate has an upper limit of 200 unique instances.`` Is there a way to do this?

  Yes, use proc transform with the count action (introduced in version 1.3).`` Your data will have to be sorted (or at least grouped) so that all like datetimes are together. A gallery example where this is done is hitcount

I've been using ploticus off and on for about 2 months now.`` Typically plotting statistical data from our ADSM backup accounting log. We are using this to trend growth and plan expansion. Recently some client or clients are out of control and using too much space. I would like to graphically display the data... Here's a slice of it....

      01/01/2000,BINC_MSN,6.321745
      01/01/2000,LEUSDB01,15.896682
      01/01/2000,MINERVA,15.880768
      01/02/2000,HIGHSMITH1,22.693413
      01/04/2000,MINERVA,16.165971

...... As you can probably tell, date,client,datum.``
I would like a stacked bar graph (x-axis = date) a different color for each client and the height of the bar determined by the 3rd field. I can't figure out the color piece (there are a total of 13 unique clients, not all appear each day).`` Any help would be appreciated.

  You can use proc tabulate with `accumfield` (a new attribute in version 1.34) to tally up each user's number for each day, to produce a matrix of numbers. Then, these values are plotted. It requires proc bars to be invoked once for each user, so it is only practical if the set of users is known in advance.``

I have a data set with mm/dd/yyyy dates in field 2 and hh:mm times in field 3. How can I plot these using the datetime scaling type?

  Ploticus datetime values have the form date.time.`` The date and the time may in any of the supported notations.`` The dot (.) separator is required.`` You can use proc getdata's `filter` attribute to concatentate fields 2 and 3 like this:

       	#proc getdata
       	file: mydata
       	filter: @@1 @@2.@@3 @@4 @@5

       	showresults: yes

I am doing a stacked bar graph, stacking the values found in fields 4, 5, and 6.`` Is there any way to use `yautorange` for this task?

  You can use proc getdata's `filter` attribute to sum up fields 4 + 5 + 6 and create a new data field holding the result. Then give yautorange the new field. Here is a sample:

       	#proc getdata
       	file: mydata
       	filter: ##declare SUM
       		##set SUM = $arithl(@@4+@@5+@@6)
       		@@1 @@2 @@3 @@SUM

       	showresults: yes

       	#proc areadef
       	yautorange: datafield=4
       	...etc..

In the results from sar -u, I can get "idle" time in %. Subtracting that from 100 would give me the total CPU load data. Is there an easy way to accomplish that within the ploticus script?

  Yes, similarly to the above example, you can use proc getdata's filter attribute.`` Suppose your idle time is in field #4:

       	#proc getdata
       	file: myfile
       	filter: ##declare CPUTOT
              	##set CPUTOT = $arith(100-@@4)
               	@@1 @@2 @@3 @@CPUTOT @@5 @@6

       	showresults: yes

I am doing a clustered bar graph, using the values found in fields 1 and 3.`` Is there any way to use `yautorange` for this task? It only uses one data field in finding the scale.

  This is probably the most asked question lately.`` As of version 1.41 you can specify multiple datafields in autorange , and they will all be scanned for minima and maxima.``

  The old solution still works too:

       	#proc getdata
       	file: mydata
       	showresults: yes
       	filter: ##declare MAX
       		##set MAX = $max(@@1,@@3)
       		@@2 @@MAX

       	#proc areadef
       	yautorange: datafield=2
       	...etc..

How can I make `autorange` work for stacked bars, or error bars?``

  Use autorange's `combomode` subattribute.``

I am producing bar graphs in postscript. There are seven different types of bars, using seven shades of gray.`` It is hard to distinguish between some of the grays, especially after photocopying.

  Beginning in Version 1.3, hatch patterns were introduced as a color option, which may be useful in getting more distinguishable bar shades.``

When I print on an Apple Laserwriter the grays look different than on an HP (w/ postscript cartridge).

  The halftoning process used to render grays on PostScript printers has some hardware dependencies, hence the differences in appearance.``

Can I use hatch patterns in pie graphs?

  No, they may only be used to fill rectangular areas such as bars.``

Why isn't vertical text displayed properly on X11?

  Ploticus doesn't store its own fonts or have its own font system; rather it uses fonts that are native to the various graphics platforms or drivers. X11 does not support vertical fonts (at least it didn't seem to when I wrote the X11 code several years ago). PostScript and PNG/GIF do support vertical fonts.``

If I had one feature request for ploticus it would be support for setting text at angles other than 0 and 90.

  This could be done for postscript rendering easily enough but would be difficult in X11 and PNG/GIF, since the underlying libraries do not support angled fonts.``

I am specifying some data using #proc trailer.`` Can I have a data statement in any proc def and pull coords out of it with #in<anyprocname>

  No. You can only have one #proc trailer per script file, and the only way to read in that data is

          #proc getdata
            #intrailer

  The only #proc that reads (or specifies) data for plotting is #proc getdata.``

  proc trailer was intended as a way to embed data but keep it at the end of the script, for convenience. #proc getdata's #intrailer operator just tells it to look at the end of the file. #intrailer starts with a pound sign (#) because action needs to be taken by the script interpreter (i.e. internal reasons).``

  If you need to embed multiple data sets, you could do it by using:

          #proc getdata
          data:  1 2
                 3 4
                 5 6
                  ..etc..

         #proc scatterplot

         #proc getdata
          data:
                 9 8
                 7 6
                 5 4
                 .. etc..

          #proc scatterplot

          ..etc.

I would like to know if there is a way to incorporate an HP-UX system date command (`date +%b%d` is the command} into a ploticus script. I would like the UNIX command to be used in the tile of #proc page, but as long as I can have the date on the graph page I would be happy.

  One way would be to use the $system() function. Here is an example:

        #declare TODAY
        #set TODAY = $system(date'+%b%d)
        #proc page
        title:  Some set of plots
               Run on: 10-SEP-2001

         ..etc.

  ``$system is described near the end of the (long) functions(pl) man page (ploticus/doc/functions.html). Any spaces in the unix command need to be represented as single quotes (').``

How can I access a data field from within a ploticus script? I tried and @@3 but no luck.

  Constructs such as @@3 only have meaning within operations that are processing a stream of data, such as a select attribute or getdata filter script.`` They have no meaning in the rest of a ploticus script.`` As of version 1.39 a new function called $dataitem(row,field) is available to retrieve specific data cells. For example, to assign variable M to the contents of the current data set, first row, first column, do this:
  `#set M = $dataitem(1,1)`

I am generating rangebars and would like to save and use the calculated statistics data set for other purposes. However, the format that proc rangebar produces is not usable.

  As of version 1.39, you can get a terser stats output (showbriefstats) and customize the row identifiers to some degree (briefstatstag). It is also easy to place the result into a file (showstatsfile).``

When generating rangebars with outliers it seems that a symbol is mandatory.`` I don't want any symbol, just a label.

  As of version 1.39 it is possible to say "none" for nearoutliersym and faroutliersym.``

I am using your package to create stock graphs, from stock data, just as you have shown in the example. It takes maybe 2 seconds to produce the graph, where on Yahoo's site, whatever they are doing, it is instantaneous (I am using a cable modem). Is there any way I can increase the performance of your package?

  The Yahoo finance site probably uses a package that is optimized for the types of graphs they produce; they may also cache the more frequently requested graphs, and you can bet they are using high-end systems that are optimized for fast web page generation and delivery.``

  Ploticus, on the other hand, is flexible and allows many, many options to be specified, including the color and style of most text and line objects. All of these options have to be interpreted at run time and this adds overhead.`` A bigger performance issue though, is that Ploticus' development philosophy has been to code the various features in a robust, simple, maintainable way, and not necessarily the most efficient way. For instance, many features are implemented using temporary scratch files rather than memory.`` Most internal lookups (variables, commands, categories, date types) are implemented as plain linear searches.`` Data are represented internally in character form, meaning that there is a lot of character to floating point conversion going on.``

  Bottlenecks often become more evident as data sets get larger or plotting procedures become more elaborate.`` Features that are suspected of being particular bottlenecks are shown below.``

  - proc getdata `filter`s
  - proc tabulate, especially with larger numbers of unique values

I have one data set with about 80 different cases represented in it. Each case has several dozen rows of data. I want to produce a rangebar on each case.`` However, looking at the examples that do similar to this, it seems as if ploticus has to process the cases one at a time and for each case scan the entire data set, selecting out the current case. This means that I will be scanning this data set 80 times which is horribly inefficient. Is there a better way?

  Yes, there is now (version 1.39) a new action in proc processdata called breaks.`` It works within a loop, and causes the data set to be scanned only once.`` It requires that the data be sorted by case.`` An example that uses this is mouse

More to come....
data display engine
Copyright Steve Grubb

Markup created by unroff 1.0, `` `` September 10, 2001.