home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The Fred Fish Collection 1.5
/
ffcollection-1-5-1992-11.iso
/
ff_disks
/
300-399
/
ff391.lzh
/
ListPlot
/
Csrc
/
ListPlot.c
< prev
next >
Wrap
C/C++ Source or Header
|
1990-10-27
|
20KB
|
719 lines
/*
* ListPlot.c
*
* Yet another plotting filter.
*
*/
#include <stdio.h>
#include <errno.h>
extern int errno;
#include <assert.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include "datatypes.h"
void ErrorExit();
char *calloc();
/* initializations */
char *Usage[] = {
"Usage: ListPlot [Options]\n",
0
};
char *Function[] = {
"Function: Yet another plotting filter. For help, enter \"ListPlot help\".\n\tFor more verbose help, enter \"ListPlot Verbose=on help=all\".\n",
"\n",
"\tListPlot supports a number of different devices.\n",
"\n",
"\tListPlot reads from stdin and writes to stdout unless input and/or\n",
"\toutput files are specified on the command line.\n",
"\tThe program accepts a file of n-tuples. Each tuple consists of\n",
"\ta sequence of space separated numbers terminated with a newline.\n",
"\tThe first element of each tuple is assumed to be the independent\n",
"\tvariable. Each remaining element is plotted against the first to\n",
"\tproduce n-1 curves.\n",
"\n",
"\tListPlot takes a number of command line arguments that may be\n",
"\tused to control the appearance of the plots.\n",
"\tFor a list of the arguments enter:\n",
"\t\tListPlot Help=All.\n",
"\n",
"\t'Boolean' values accept values such as true, false,\n",
"\tyes, no, on, and off. (ex. PlotColor=yes)\n",
"\n",
"\t'String' values expect the strings to entered as\n",
"\tindicated and is case sensitive. (ex. Domain=All)\n",
"\n",
"\t'Dbl' values expect real numbers. (ex. AspectRatio=1.0)\n",
"\n",
"\t'Interval' values expect a pair of comma separated reals.\n",
"\t\t(ex. Range=-1.0,3.0)\n",
"\n",
"\t'Set' values expect a list of comma separated elements enclosed in\n",
"\tcurly braces ({}). (ex. LineStyle={MS,MMS,MSmmS})\n",
"\n",
"\tThe title and label variables accept strings that include\n",
"\tthe following control sequences:\n",
"\t\t#u: move up to superscript position (ended with #d)\n",
"\t\t#d: move down to subscript position (ended with #u)\n",
"\t\t#b: backspace to allow overprinting\n",
"\t\t##: the number symbol\n",
"\t\t#+: toggle overline mode\n",
"\t\t#-: toggle underline mode\n",
"\t\t#gx: Greek letter corresponding to Roman letter x\n",
"\n",
0
};
bool GraphicsInProgress = FALSE;
/* argument definitions */
/* GoldenRatio = (1+Sqrt(5))/2 */
#define GOLDENRATIO 1.6180339887499
#define ASPECTRATIO 1.0/GOLDENRATIO
char *H_AngularUnit[] = {
"\t'AngularUnit' specifies the angular unit of measure\n",
"\tused for polar plots. For angles in radians use\n",
"\t\tAngularUnit=radians\n",
(char *)NULL
};
VALUE V_AngularUnit;
ARGDEF A_AngularUnit = {
&V_AngularUnit, /* variable */
"AngularUnit", /* ID */
"degrees|radians", /* options */
"string|string", /* format */
"degrees", /* default */
"string", /* Default type */
H_AngularUnit
};
char *H_AnnotationScale[] = {
"\t'AnnotationScale' controls the size of the characters\n",
"\tused to annotate the axises.\n",
(char *)NULL
};
VALUE V_AnnotationScale;
ARGDEF A_AnnotationScale = {
&V_AnnotationScale, /* variable */
"AnnotationScale", /* ID */
"dbl", /* options */
"dbl", /* format */
"0.50", /* default */
"dbl", /* Default type */
H_AnnotationScale
};
char *H_AspectRatio[] = {
"\t'AspectRatio' controls the relative lengths of the vertical to\n",
"\thorizontal axes. The default is 1.0/GoldenRatio.\n",
"\t\tAspectRatio=0.618\n",
"\tIf set this value overrides the value of 'ViewPort'.\n",
(char *)NULL
};
VALUE V_AspectRatio;
ARGDEF A_AspectRatio = {
&V_AspectRatio, /* variable */
"AspectRatio", /* ID */
"dbl|Automatic", /* options */
"dbl|string", /* format */
"0.61803399", /* default */
"dbl", /* Default type */
H_AspectRatio
};
char *H_Boxed[] = {
"\t'Boxed' adds axes to the edges of the plot.\n",
"\tIf 'Boxed is given a boolean value then axes are placed on\n",
"\tall of the edges. If 'Boxed' is given a string consisting\n",
"\tof one or more of 't','b','r','l' then axes are added to\n",
"\ttop, bottom, right and left edges respectively.\n",
(char *)NULL
};
VALUE V_Boxed;
ARGDEF A_Boxed = {
&V_Boxed, /* variable */
"Boxed", /* ID */
"boolean|*", /* options */
"boolean|string", /* format */
"yes", /* default */
"boolean", /* Default type */
H_Boxed
};
char *H_Domain[] = {
"\t'Domain' may be used to specify the bounds on the X axis.\n",
(char *)NULL
};
VALUE V_Domain;
ARGDEF A_Domain = {
&V_Domain, /* variable */
"Domain", /* ID */
"interval|All|Automatic", /* options */
"interval|string|string", /* format */
"All", /* default */
"string", /* Default type */
H_Domain
};
char *H_Gridding[] = {
"\t'Gridding' puts a grid on the plot.\n",
(char *)NULL
};
VALUE V_Gridding;
ARGDEF A_Gridding = {
&V_Gridding, /* variable */
"Gridding", /* ID */
"boolean", /* options */
"boolean", /* format */
"no", /* default */
"boolean", /* Default type */
H_Gridding
};
/* N.B. Help is treated differently than other variables and its
* arguments should only be of type "string"!
*/
char *H_Help[] = {
"\t'Help' provides some descriptive text for the user-settable\n",
"\tplotting variables. If the variable 'Verbose' is set then\n",
"\tan extended description is provided. To set verbose enter\n",
"\t\tListPlot Verbose=yes Help=[variable name | All].\n",
(char *)NULL
};
VALUE V_Help;
ARGDEF A_Help = {
&V_Help, /* variable */
"Help", /* ID */
"All|all|*", /* options */
"string|string|string", /* format */
"All", /* default */
"string", /* Default type */
H_Help
};
char *H_LabelScale[] = {
"\t'LabelScale' specifies the relative size of the vertical and\n",
"\thorizontal axis labels. The typical range is [0.5 - 2.0].\n",
(char *)NULL
};
VALUE V_LabelScale;
ARGDEF A_LabelScale = {
&V_LabelScale, /* variable */
"LabelScale", /* ID */
"dbl", /* options */
"dbl", /* format */
"0.85", /* default*/
"dbl", /* Default type */
H_LabelScale
};
char *H_LineColor[] = {
"\t'LineColor' may be used to specify a list of line colors for\n",
"\tplots with multiple curves if this feature is supported for\n",
"\ta particular output device.\n",
(char *)NULL
};
VALUE V_LineColor;
ARGDEF A_LineColor = {
&V_LineColor, /* variable */
"LineColor", /* ID */
"set", /* options */
"set", /* format */
"{Black,Red,Green,Blue,Yellow}", /* default*/
"set", /* Default type */
H_LineColor
};
char *H_LineStyle[] = {
"\t'LineStyle' may be used to specify a list of line styles for\n",
"\tplots with multiple curves. Each linestyle is specified as\n",
"\ta sequence of pen down... pen up elements. The elements are encoded\n",
"\tusing the following characters to indicate element lengths:\n",
"\t\t'm':\t250 micron mark\n",
"\t\t'M':\t4 m's or a 1mm mark\n",
"\t\t's':\t250 micron space\n",
"\t\t'S':\t4 s's or a 1mm space\n",
"\n",
"\tFor example, a set of line styles might be indicated\n",
"\t\tLineStyle={MS,MMSS,MMSmmS,mmS,mmSmmSMMS}\n",
(char *)NULL
};
VALUE V_LineStyle;
ARGDEF A_LineStyle = {
&V_LineStyle, /* variable */
"LineStyle", /* ID */
"set", /* options */
"set", /* format */
"{MS,MMSS,MMSmmS,mmS,mmSmmSMMS}",/*default*/
"set", /* Default type */
H_LineStyle
};
char *H_Origin[] = {
"\tThe 'Origin' option is not yet implemented. It is intended\n",
"\tthat this feature beused to specify the origin of the plot.\n",
(char *)NULL
};
VALUE V_Origin;
ARGDEF A_Origin = {
&V_Origin, /* variable */
"Origin", /* ID */
"interval|Automatic|Median", /* options */
"interval|string|string", /* format */
"Automatic", /* default */
"string", /* Default type */
H_Origin
};
char *H_PlotColor[] = {
"\t'PlotColor' if TRUE causes the plot to generated in color if this\n",
"\tfeature is supported on a particular output device.\n",
(char *)NULL
};
VALUE V_PlotColor;
ARGDEF A_PlotColor = {
&V_PlotColor, /* variable */
"PlotColor", /* ID */
"boolean", /* options */
"boolean", /* format */
"no", /* default */
"boolean", /* Default type */
H_PlotColor
};
char *H_PlotDevice[] = {
"\t'PlotDevice' specifies output device type.\n",
(char *)NULL
};
VALUE V_PlotDevice;
ARGDEF A_PlotDevice = {
&V_PlotDevice, /* variable */
"PlotDevice", /* ID */
"amiga|printer|iff|hp|aegis|postscript",/* options */
"string|string|string|string|string|string",/* format */
"amiga", /* default */
"string", /* Default type */
H_PlotDevice
};
char *H_PlotJoined[] = {
"\t'PlotJoined' is set connects each data point with a line in the\n",
"\tcurrent line style. (ex PlotJoined=on )\n",
(char *)NULL
};
VALUE V_PlotJoined;
ARGDEF A_PlotJoined = {
&V_PlotJoined, /* variable */
"PlotJoined", /* ID */
"boolean", /* options */
"boolean", /* format */
"yes", /* default */
"boolean", /* Default type */
H_PlotJoined
};
char *H_PlotPoints[] = {
"\t'PlotPoints' if set causes symbols to be plotted in the current\n",
"\tsymbol style at each data point. (ex. PlotPoints=true )\n",
(char *)NULL
};
VALUE V_PlotPoints;
ARGDEF A_PlotPoints = {
&V_PlotPoints, /* variable */
"PlotPoints", /* ID */
"boolean", /* options */
"boolean", /* format */
"false", /* default */
"boolean", /* Default type */
H_PlotPoints
};
char *H_PlotTitle[] = {
"\t'PlotTitle' takes the plot title as an argument.\n",
"\tGreek symbols may be specified by preceding a character by\n",
"\t'#g'. Superscripts and subscripts may be specified using\n",
"\t'#u', '#d' respectively.\n",
(char *)NULL
};
VALUE V_PlotTitle;
ARGDEF A_PlotTitle = {
&V_PlotTitle, /* variable */
"PlotTitle", /* ID */
"*", /* options */
"string", /* format */
"", /* default */
"string", /* Default type */
H_PlotTitle
};
char *H_PlotType[] = {
"\t'PlotType' specifies the 'graph paper' upon which the plot is drawn.\n",
"\tThe current implementation plots in\n",
"\t\tlinear-linear,\n",
"\t\tlog-linear,\n",
"\t\tlinear-log,\n",
"\t\tlog-log, and\n",
"\t\tpolar\n",
"\tformats.\n",
"\tFor the log type plots, the log of the data is computed\n",
"\tby ListPlot.\n",
"\tFor polar plots, see also 'AngularUnit' and 'PolarVariable'.\n",
(char *)NULL
};
VALUE V_PlotType;
ARGDEF A_PlotType = {
&V_PlotType, /* variable */
"PlotType", /* ID */
"linlin|loglin|linlog|loglog|polar",/* options */
"string|string|string|string|string",/* format */
"linlin", /* default */
"string", /* Default type */
H_PlotType
};
char *H_PointScale[] = {
"\t'PointScale' controls the relative size of the data point symbols\n",
"\twhen data point symbols are being plotted.\n",
(char *)NULL
};
VALUE V_PointScale;
ARGDEF A_PointScale = {
&V_PointScale, /* variable */
"PointScale", /* ID */
"dbl", /* options */
"dbl", /* format */
"1.0", /* default */
"dbl", /* Default type */
H_PointScale
};
char *H_PointSymbol[] = {
"\t'PointSymbol' specifies a list of symbols to be used when plotting\n",
"\tdata points. The symbols types are encoded as integers.\n",
"\tSee the PLPLOT library documentation to find the symbols\n",
"\tavailable.\n",
(char *)NULL
};
VALUE V_PointSymbol;
ARGDEF A_PointSymbol = {
&V_PointSymbol, /* variable */
"PointSymbol", /* ID */
"Automatic|set", /* options */
"string|set", /* format */
"Automatic", /* default */
"string", /* Default type */
H_PointSymbol
};
char *H_PolarVariable[] = {
"\t'PolarVariable' for polar plots is used to specify\n",
"\twhether the independent variable is angular or radial.\n",
(char *)NULL
};
VALUE V_PolarVariable;
ARGDEF A_PolarVariable = {
&V_PolarVariable, /* variable */
"PolarVariable", /* ID */
"angle|radius", /* options */
"string|string", /* format */
"angle", /* default */
"string", /* Default type */
H_PolarVariable
};
char *H_Orientation[] = {
"\t'Orientation' controls whether the plot is displayed in\n",
"\tlandscape or portrait orientation.\n",
(char *)NULL
};
VALUE V_Orientation;
ARGDEF A_Orientation = {
&V_Orientation, /* variable */
"Orientation", /* ID */
"portrait|landscape", /* options */
"string|string", /* format */
"landscape", /* default */
"string", /* Default type */
H_Orientation
};
char *H_Range[] = {
"\t'Range' specifies the y axis bounds. (ex. Range=-1,1 )\n",
(char *)NULL
};
VALUE V_Range;
ARGDEF A_Range = {
&V_Range, /* variable */
"Range", /* ID */
"interval|All|Automatic", /* options */
"interval|string|string", /* format */
"All", /* default */
"string", /* Default type */
H_Range
};
char *H_SubPages[] = {
"\t'SubPages' specifies the number of plots on a pages.\n",
"\tThis is a vestige of PLPLOT and I am not sure this has any use\n",
"\twithin the context of 'ListPlot. It might be useful for\n",
"\tcontrolling the size of the plots but the 'ViewPort' might be\n",
"\ta more direct solution.\n",
(char *)NULL
};
VALUE V_SubPages;
ARGDEF A_SubPages = {
&V_SubPages, /* variable */
"SubPages", /* ID */
"interval", /* options */
"interval", /* format */
"1.0,1.0", /* default */
"interval", /* Default type */
H_SubPages
};
char *H_SupplyAbscissa[] = {
"\t'SupplyAbscissa' if set causes ListPlot to supply a value for\n",
"\tthe independent variable.\n",
(char *)NULL
};
VALUE V_SupplyAbscissa;
ARGDEF A_SupplyAbscissa = {
&V_SupplyAbscissa, /* variable */
"SupplyAbscissa", /* ID */
"boolean", /* options */
"boolean", /* format */
"no", /* default */
"boolean", /* Default type */
H_SupplyAbscissa
};
char *H_TitleScale[] = {
"\t'TitleScale' controls the relative size of the title text.\n",
(char *)NULL
};
VALUE V_TitleScale;
ARGDEF A_TitleScale = {
&V_TitleScale, /* variable */
"TitleScale", /* ID */
"dbl", /* options */
"dbl", /* format */
"1.0", /* default */
"dbl", /* Default type */
H_TitleScale
};
char *H_UseInputFile[] = {
"\t'UseInputFile' permits the specification of an input file if\n",
"\tyou would rather not use stdin.\n",
(char *)NULL
};
VALUE V_UseInputFile;
ARGDEF A_UseInputFile = {
&V_UseInputFile, /* variable */
"UseInputFile", /* ID */
"*", /* options */
"string", /* format */
"", /* default */
"string", /* Default type */
H_UseInputFile
};
char *H_UseOutputFile[] = {
"\t'UseOutputFile' permits the specification of an output file if\n",
"\tyou would rather not use stdout.\n",
(char *)NULL
};
VALUE V_UseOutputFile;
ARGDEF A_UseOutputFile = {
&V_UseOutputFile, /* variable */
"UseOutputFile", /* ID */
"*", /* options */
"string", /* format */
"", /* default */
"string", /* Default type */
H_UseOutputFile
};
/* Not used. V_AspectRatio may be used to control viewport in a nicer way */
char *H_Verbose[] = {
"\t'Verbose' if set causes extended messaging.\n",
(char *)NULL
};
VALUE V_Verbose;
ARGDEF A_Verbose = {
&V_Verbose, /* variable */
"Verbose", /* ID */
"boolean", /* options */
"boolean", /* format */
"off", /* default */
"boolean", /* Default type */
H_Verbose
};
char *H_ViewPort[] = {
"\t'ViewPort' allows control over the size of a plot. Takes\n",
"\ta viewing rectangle diagonal as an argument.\n",
"\t\t(ex. ViewPort=\\{0.1,0.3, 0.9,0.6\\} )\n",
(char *)NULL
};
VALUE V_ViewPort;
ARGDEF A_ViewPort = {
&V_ViewPort, /* variable */
"ViewPort", /* ID */
"rect", /* options */
"rect", /* format */
"{0.1,0.1,0.9,0.9}", /* default */
"rect", /* Default type */
H_ViewPort
};
char *H_XLabel[] = {
"\t'XLabel' specifies X axis label. Greek characters may be included\n",
"\tby preceding the character with '#g'. Superscripts and subscripts\n",
"\tmay be included using '#u' and '#d' control sequences respectively.\n",
(char *)NULL
};
VALUE V_XLabel;
ARGDEF A_XLabel = {
&V_XLabel, /* variable */
"XLabel", /* ID */
"*", /* options */
"string", /* format */
"", /* default */
"string", /* Default type */
H_XLabel
};
char *H_XTick[] = {
"\t'XTick' controls the spacing of major axis ticks and the number\n",
"\tof minor subdivisions. (ex. XTick=0.1,10 indicates major ticks at\n",
"\tunits of 0.1 with 10 minor subdivisions.)\n",
(char *)NULL
};
VALUE V_XTick;
ARGDEF A_XTick = {
&V_XTick, /* variable */
"XTick", /* ID */
"Automatic|interval", /* options */
"string|interval", /* format */
"Automatic", /* default */
"string", /* Default type */
H_XTick
};
char *H_YLabel[] = {
"\t'YLabel' specifies Y axis label. Greek characters may be included\n",
"\tby preceding the character with '#g'. Superscripts and subscripts\n",
"\tmay be included using '#u' and '#d' control sequences respectively.\n",
(char *)NULL
};
VALUE V_YLabel;
ARGDEF A_YLabel = {
&V_YLabel, /* variable */
"YLabel", /* ID */
"*", /* options */
"string", /* format */
"", /* default */
"string", /* Default type */
H_YLabel
};
char *H_YTick[] = {
"\t'YTick' controls the spacing of major axis ticks and the number\n",
"\tof minor subdivisions. (ex. YTick=0.1,10 indicates major ticks at\n",
"\tunits of 0.1 with 10 minor subdivisions.)\n",
(char *)NULL
};
VALUE V_YTick;
ARGDEF A_YTick = {
&V_YTick, /* variable */
"YTick", /* ID */
"Automatic|interval", /* options */
"string|interval", /* format */
"Automatic", /* default */
"string", /* Default type */
H_YTick
};
ARGDEF *SymbolTable[] = {
&A_AngularUnit,
&A_AnnotationScale,
&A_AspectRatio,
&A_Boxed,
&A_Domain,
&A_Gridding,
&A_Help,
&A_LabelScale,
&A_LineColor,
&A_LineStyle,
&A_Orientation,
&A_Origin,
&A_PlotColor,
&A_PlotJoined,
&A_PlotPoints,
&A_PointScale,
&A_PointSymbol,
&A_PlotTitle,
&A_PlotDevice,
&A_PlotType,
&A_PolarVariable,
&A_Range,
&A_SubPages,
&A_SupplyAbscissa,
&A_TitleScale,
&A_UseInputFile,
&A_UseOutputFile,
&A_Verbose,
&A_ViewPort,
&A_XLabel,
&A_YLabel,
&A_XTick,
&A_YTick,
(ARGDEF *)NULL
};
main(argc, argv)
int argc;
char **argv;
{
register int i;
int NTuples, TupleSize;
FLOAT **Data;
FILE *Fp;
void InterruptHandler();
#ifdef ANSI_C
FLOAT **GetData(FILE *, int *, int *);
void ListPlot(FLOAT **,int ,int );
#else
FLOAT **GetData();
void ListPlot();
#endif
get_args(argc, argv, SymbolTable, Usage, Function);
if (VtoBoolean(V_Verbose)) {
fprintf(stderr, "Arg values:\n");
for (i=0; SymbolTable[i]; i++) {
fputc('\t' ,stderr);
PrintArg(stderr, SymbolTable[i]);
}
}
if (signal(SIGINT, SIG_IGN) != SIG_IGN)
signal(SIGINT, InterruptHandler);
if (strlen(V_UseInputFile.val_u.udt_string) > 0) {
if ((Fp = fopen(V_UseInputFile.val_u.udt_string, "r")) == (FILE *)NULL) {
perror(V_UseInputFile.val_u.udt_string);
exit(errno);
}
} else {
Fp = stdin;
}
if (strlen(V_UseOutputFile.val_u.udt_string) > 0) {
if (!freopen(V_UseOutputFile.val_u.udt_string, "w", stdout)) {
perror(V_UseOutputFile.val_u.udt_string);
exit(errno);
}
}
if ((Data = GetData(Fp, &NTuples, &TupleSize)) == (FLOAT **)NULL) {
/* error */
fprintf(stderr, "Unable to read data...\n");
ErrorExit();
}
ListPlot(Data, NTuples, TupleSize);
}
void
InterruptHandler()
{
ErrorExit(); /* will not return */
return; /* To satisfy some compilers */
}
void
ErrorExit()
{
if (GraphicsInProgress)
plend();
exit(0);
}