mirror of
https://github.com/ultimatepp/ultimatepp.git
synced 2026-05-17 06:06:00 -06:00
800 lines
26 KiB
C
800 lines
26 KiB
C
/*====================================================================*
|
|
- Copyright (C) 2001 Leptonica. All rights reserved.
|
|
- This software is distributed in the hope that it will be
|
|
- useful, but with NO WARRANTY OF ANY KIND.
|
|
- No author or distributor accepts responsibility to anyone for the
|
|
- consequences of using this software, or for whether it serves any
|
|
- particular purpose or works at all, unless he or she says so in
|
|
- writing. Everyone is granted permission to copy, modify and
|
|
- redistribute this source code, for commercial or non-commercial
|
|
- purposes, with the following restrictions: (1) the origin of this
|
|
- source code must not be misrepresented; (2) modified versions must
|
|
- be plainly marked as such; and (3) this notice may not be removed
|
|
- or altered from any source or modified source distribution.
|
|
*====================================================================*/
|
|
|
|
/*
|
|
* gplot.c
|
|
*
|
|
* Basic plotting functions
|
|
* GPLOT *gplotCreate()
|
|
* void gplotDestroy()
|
|
* l_int32 gplotAddPlot()
|
|
* l_int32 gplotSetScaling()
|
|
* l_int32 gplotMakeOutput()
|
|
* l_int32 gplotGenCommandFile()
|
|
* l_int32 gplotGenDataFiles()
|
|
*
|
|
* Quick and dirty plots
|
|
* l_int32 gplotSimple1()
|
|
* l_int32 gplotSimple2()
|
|
* l_int32 gplotSimpleN()
|
|
*
|
|
* Serialize for I/O
|
|
* GPLOT *gplotRead()
|
|
* l_int32 gplotWrite()
|
|
*
|
|
*
|
|
* Utility for programmatic plotting using gnuplot 7.3.2 or later
|
|
* Enabled:
|
|
* - output to png (color), ps (mono), x11 (color), latex (mono)
|
|
* - optional title for graph
|
|
* - optional x and y axis labels
|
|
* - multiple plots on one frame
|
|
* - optional title for each plot on the frame
|
|
* - optional log scaling on either or both axes
|
|
* - choice of 5 plot styles for each plot
|
|
* - choice of 2 plot modes, either using one input array
|
|
* (Y vs index) or two input arrays (Y vs X). This
|
|
* choice is made implicitly depending on the number of
|
|
* input arrays.
|
|
*
|
|
* Usage:
|
|
* gplotCreate() initializes for plotting
|
|
* gplotAddPlot() for each plot on the frame
|
|
* gplotMakeOutput() to generate all output files and run gnuplot
|
|
* gplotDestroy() to clean up
|
|
*
|
|
* Example of use:
|
|
* gplot = gplotCreate("tempskew", GPLOT_PNG, "Skew score vs angle",
|
|
* "angle (deg)", "score");
|
|
* gplotAddPlot(gplot, natheta, nascore1, GPLOT_LINES, "plot 1");
|
|
* gplotAddPlot(gplot, natheta, nascore2, GPLOT_POINTS, "plot 2");
|
|
* gplotSetScaling(gplot, GPLOT_LOG_SCALE_Y);
|
|
* gplotMakeOutput(gplot);
|
|
* gplotDestroy(&gplot);
|
|
*
|
|
* Note for output to GPLOT_LATEX:
|
|
* This creates latex output of the plot, named <rootname>.tex.
|
|
* It needs to be placed in a latex file <latexname>.tex
|
|
* that precedes the plot output with, at a minimum:
|
|
* \documentclass{article}
|
|
* \begin{document}
|
|
* and ends with
|
|
* \end{document}
|
|
* You can then generate a dvi file <latexname>.dvi using
|
|
* latex <latexname>.tex
|
|
* and a PostScript file <psname>.ps from that using
|
|
* dvips -o <psname>.ps <latexname>.dvi
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include "allheaders.h"
|
|
|
|
/* MS VC++ can't handle array initialization with static consts ! */
|
|
#define L_BUF_SIZE 512
|
|
#define MAX_NUM_GPLOTS 40
|
|
|
|
const char *gplotstylenames[] = {"with lines",
|
|
"with points",
|
|
"with impulses",
|
|
"with linespoints",
|
|
"with dots"};
|
|
const char *gplotfilestyles[] = {"LINES",
|
|
"POINTS",
|
|
"IMPULSES",
|
|
"LINESPOINTS",
|
|
"DOTS"};
|
|
const char *gplotfileoutputs[] = {"",
|
|
"PNG",
|
|
"PS",
|
|
"EPS",
|
|
"X11",
|
|
"LATEX"};
|
|
|
|
|
|
/*-----------------------------------------------------------------*
|
|
* Basic Plotting Functions *
|
|
*-----------------------------------------------------------------*/
|
|
/*!
|
|
* gplotCreate()
|
|
*
|
|
* Input: rootname (root for all output files)
|
|
* outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11,
|
|
* GPLOT_LATEX)
|
|
* title (<optional> overall title)
|
|
* xlabel (<optional> x axis label)
|
|
* ylabel (<optional> y axis label)
|
|
* Return: gplot, or null on error
|
|
*
|
|
* Notes:
|
|
* (1) This initializes the plot.
|
|
* (2) The 'title', 'xlabel' and 'ylabel' strings can have spaces,
|
|
* double quotes and backquotes, but not single quotes.
|
|
*/
|
|
GPLOT *
|
|
gplotCreate(const char *rootname,
|
|
l_int32 outformat,
|
|
const char *title,
|
|
const char *xlabel,
|
|
const char *ylabel)
|
|
{
|
|
char buf[L_BUF_SIZE];
|
|
GPLOT *gplot;
|
|
|
|
PROCNAME("gplotCreate");
|
|
|
|
if (!rootname)
|
|
return (GPLOT *)ERROR_PTR("rootname not defined", procName, NULL);
|
|
if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
|
|
outformat != GPLOT_EPS && outformat != GPLOT_X11 &&
|
|
outformat != GPLOT_LATEX)
|
|
return (GPLOT *)ERROR_PTR("outformat invalid", procName, NULL);
|
|
|
|
if ((gplot = (GPLOT *)CALLOC(1, sizeof(GPLOT))) == NULL)
|
|
return (GPLOT *)ERROR_PTR("gplot not made", procName, NULL);
|
|
gplot->cmddata = sarrayCreate(0);
|
|
gplot->datanames = sarrayCreate(0);
|
|
gplot->plotdata = sarrayCreate(0);
|
|
gplot->plottitles = sarrayCreate(0);
|
|
gplot->plotstyles = numaCreate(0);
|
|
|
|
/* Save title, labels, rootname, outformat, cmdname, outname */
|
|
gplot->rootname = stringNew(rootname);
|
|
gplot->outformat = outformat;
|
|
snprintf(buf, L_BUF_SIZE, "%s.cmd", rootname);
|
|
gplot->cmdname = stringNew(buf);
|
|
if (outformat == GPLOT_PNG)
|
|
snprintf(buf, L_BUF_SIZE, "%s.png", rootname);
|
|
else if (outformat == GPLOT_PS)
|
|
snprintf(buf, L_BUF_SIZE, "%s.ps", rootname);
|
|
else if (outformat == GPLOT_EPS)
|
|
snprintf(buf, L_BUF_SIZE, "%s.eps", rootname);
|
|
else if (outformat == GPLOT_LATEX)
|
|
snprintf(buf, L_BUF_SIZE, "%s.tex", rootname);
|
|
else /* outformat == GPLOT_X11 */
|
|
buf[0] = '\0';
|
|
gplot->outname = stringNew(buf);
|
|
if (title) gplot->title = stringNew(title);
|
|
if (xlabel) gplot->xlabel = stringNew(xlabel);
|
|
if (ylabel) gplot->ylabel = stringNew(ylabel);
|
|
|
|
return gplot;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotDestroy()
|
|
*
|
|
* Input: &gplot (<to be nulled>)
|
|
* Return: void
|
|
*/
|
|
void
|
|
gplotDestroy(GPLOT **pgplot)
|
|
{
|
|
GPLOT *gplot;
|
|
|
|
PROCNAME("gplotDestroy");
|
|
|
|
if (pgplot == NULL) {
|
|
L_WARNING("ptr address is null!", procName);
|
|
return;
|
|
}
|
|
|
|
if ((gplot = *pgplot) == NULL)
|
|
return;
|
|
|
|
FREE(gplot->rootname);
|
|
FREE(gplot->cmdname);
|
|
sarrayDestroy(&gplot->cmddata);
|
|
sarrayDestroy(&gplot->datanames);
|
|
sarrayDestroy(&gplot->plotdata);
|
|
sarrayDestroy(&gplot->plottitles);
|
|
numaDestroy(&gplot->plotstyles);
|
|
FREE(gplot->outname);
|
|
if (gplot->title)
|
|
FREE(gplot->title);
|
|
if (gplot->xlabel)
|
|
FREE(gplot->xlabel);
|
|
if (gplot->ylabel)
|
|
FREE(gplot->ylabel);
|
|
|
|
FREE(gplot);
|
|
*pgplot = NULL;
|
|
return;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotAddPlot()
|
|
*
|
|
* Input: nax (<optional> numa: set to null for Y_VS_I;
|
|
* required for Y_VS_X)
|
|
* nay (numa: required for both Y_VS_I and Y_VS_X)
|
|
* plotstyle (GPLOT_LINES, GPLOT_POINTS, GPLOT_IMPULSES,
|
|
* GPLOT_LINESPOINTS, GPLOT_DOTS)
|
|
* plottitle (<optional> title for individual plot)
|
|
* Return: 0 if OK, 1 on error
|
|
*
|
|
* Notes:
|
|
* (1) There are 2 options for (x,y) values:
|
|
* o To plot an array vs the index, set nax = NULL.
|
|
* o To plot one array vs another, use both nax and nay.
|
|
* (2) If nax is defined, it must be the same size as nay.
|
|
* (3) The 'plottitle' string can have spaces, double
|
|
* quotes and backquotes, but not single quotes.
|
|
*/
|
|
l_int32
|
|
gplotAddPlot(GPLOT *gplot,
|
|
NUMA *nax,
|
|
NUMA *nay,
|
|
l_int32 plotstyle,
|
|
const char *plottitle)
|
|
{
|
|
char buf[L_BUF_SIZE];
|
|
char emptystring[] = "";
|
|
char *datastr, *title;
|
|
l_int32 n, i;
|
|
l_float32 valx, valy, startx, delx;
|
|
SARRAY *sa;
|
|
|
|
PROCNAME("gplotAddPlot");
|
|
|
|
if (!gplot)
|
|
return ERROR_INT("gplot not defined", procName, 1);
|
|
if (!nay)
|
|
return ERROR_INT("nay not defined", procName, 1);
|
|
if (plotstyle != GPLOT_LINES && plotstyle != GPLOT_POINTS &&
|
|
plotstyle != GPLOT_IMPULSES && plotstyle != GPLOT_LINESPOINTS &&
|
|
plotstyle != GPLOT_DOTS)
|
|
return ERROR_INT("invalid plotstyle", procName, 1);
|
|
|
|
n = numaGetCount(nay);
|
|
numaGetXParameters(nay, &startx, &delx);
|
|
if (nax) {
|
|
if (n != numaGetCount(nax))
|
|
return ERROR_INT("nax and nay sizes differ", procName, 1);
|
|
}
|
|
|
|
/* Save plotstyle and plottitle */
|
|
numaAddNumber(gplot->plotstyles, plotstyle);
|
|
if (plottitle) {
|
|
title = stringNew(plottitle);
|
|
sarrayAddString(gplot->plottitles, title, L_INSERT);
|
|
}
|
|
else
|
|
sarrayAddString(gplot->plottitles, emptystring, L_COPY);
|
|
|
|
/* Generate and save data filename */
|
|
gplot->nplots++;
|
|
snprintf(buf, L_BUF_SIZE, "%s.data.%d", gplot->rootname, gplot->nplots);
|
|
sarrayAddString(gplot->datanames, buf, L_COPY);
|
|
|
|
/* Generate data and save as a string */
|
|
sa = sarrayCreate(n);
|
|
for (i = 0; i < n; i++) {
|
|
if (nax)
|
|
numaGetFValue(nax, i, &valx);
|
|
else
|
|
valx = startx + i * delx;
|
|
numaGetFValue(nay, i, &valy);
|
|
snprintf(buf, L_BUF_SIZE, "%f %f\n", valx, valy);
|
|
sarrayAddString(sa, buf, L_COPY);
|
|
}
|
|
datastr = sarrayToString(sa, 0);
|
|
sarrayAddString(gplot->plotdata, datastr, L_INSERT);
|
|
sarrayDestroy(&sa);
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotSetScaling()
|
|
*
|
|
* Input: gplot
|
|
* scaling (GPLOT_LINEAR_SCALE, GPLOT_LOG_SCALE_X,
|
|
* GPLOT_LOG_SCALE_Y, GPLOT_LOG_SCALE_X_Y)
|
|
* Return: 0 if OK; 1 on error
|
|
*
|
|
* Notes:
|
|
* (1) By default, the x and y axis scaling is linear.
|
|
* (2) Call this function to set semi-log or log-log scaling.
|
|
*/
|
|
l_int32
|
|
gplotSetScaling(GPLOT *gplot,
|
|
l_int32 scaling)
|
|
{
|
|
PROCNAME("gplotSetScaling");
|
|
|
|
if (!gplot)
|
|
return ERROR_INT("gplot not defined", procName, 1);
|
|
if (scaling != GPLOT_LINEAR_SCALE &&
|
|
scaling != GPLOT_LOG_SCALE_X &&
|
|
scaling != GPLOT_LOG_SCALE_Y &&
|
|
scaling != GPLOT_LOG_SCALE_X_Y)
|
|
return ERROR_INT("invalid gplot scaling", procName, 1);
|
|
gplot->scaling = scaling;
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotMakeOutput()
|
|
*
|
|
* Input: gplot
|
|
* Return: 0 if OK; 1 on error
|
|
*
|
|
* Notes:
|
|
* (1) This uses gplot and the new arrays to add a plot
|
|
* to the output, by writing a new data file and appending
|
|
* the appropriate plot commands to the command file.
|
|
* (2) The gnuplot program for windows is wgnuplot.exe. The
|
|
* standard gp426win32 distribution does not have a X11 terminal.
|
|
*/
|
|
l_int32
|
|
gplotMakeOutput(GPLOT *gplot)
|
|
{
|
|
char buf[L_BUF_SIZE];
|
|
|
|
PROCNAME("gplotMakeOutput");
|
|
|
|
if (!gplot)
|
|
return ERROR_INT("gplot not defined", procName, 1);
|
|
|
|
gplotGenCommandFile(gplot);
|
|
gplotGenDataFiles(gplot);
|
|
|
|
#ifndef COMPILER_MSVC
|
|
if (gplot->outformat != GPLOT_X11)
|
|
snprintf(buf, L_BUF_SIZE, "gnuplot %s &", gplot->cmdname);
|
|
else
|
|
snprintf(buf, L_BUF_SIZE,
|
|
"gnuplot -persist -geometry +10+10 %s &", gplot->cmdname);
|
|
#else
|
|
if (gplot->outformat != GPLOT_X11)
|
|
snprintf(buf, L_BUF_SIZE, "wgnuplot %s", gplot->cmdname);
|
|
else
|
|
snprintf(buf, L_BUF_SIZE,
|
|
"wgnuplot -persist %s", gplot->cmdname);
|
|
#endif /* COMPILER_MSVC */
|
|
system(buf);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotGenCommandFile()
|
|
*
|
|
* Input: gplot
|
|
* Return: 0 if OK, 1 on error
|
|
*/
|
|
l_int32
|
|
gplotGenCommandFile(GPLOT *gplot)
|
|
{
|
|
char buf[L_BUF_SIZE];
|
|
char *cmdstr, *plottitle, *dataname;
|
|
l_int32 i, plotstyle, nplots;
|
|
FILE *fp;
|
|
|
|
PROCNAME("gplotGenCommandFile");
|
|
|
|
if (!gplot)
|
|
return ERROR_INT("gplot not defined", procName, 1);
|
|
|
|
/* Remove any previous command data */
|
|
sarrayClear(gplot->cmddata);
|
|
|
|
/* Generate command data instructions */
|
|
if (gplot->title) { /* set title */
|
|
snprintf(buf, L_BUF_SIZE, "set title '%s'", gplot->title);
|
|
sarrayAddString(gplot->cmddata, buf, L_COPY);
|
|
}
|
|
if (gplot->xlabel) { /* set xlabel */
|
|
snprintf(buf, L_BUF_SIZE, "set xlabel '%s'", gplot->xlabel);
|
|
sarrayAddString(gplot->cmddata, buf, L_COPY);
|
|
}
|
|
if (gplot->ylabel) { /* set ylabel */
|
|
snprintf(buf, L_BUF_SIZE, "set ylabel '%s'", gplot->ylabel);
|
|
sarrayAddString(gplot->cmddata, buf, L_COPY);
|
|
}
|
|
|
|
if (gplot->outformat == GPLOT_PNG) /* set terminal type and output */
|
|
snprintf(buf, L_BUF_SIZE, "set terminal png; set output '%s'",
|
|
gplot->outname);
|
|
else if (gplot->outformat == GPLOT_PS)
|
|
snprintf(buf, L_BUF_SIZE, "set terminal postscript; set output '%s'",
|
|
gplot->outname);
|
|
else if (gplot->outformat == GPLOT_EPS)
|
|
snprintf(buf, L_BUF_SIZE,
|
|
"set terminal postscript eps; set output '%s'",
|
|
gplot->outname);
|
|
else if (gplot->outformat == GPLOT_LATEX)
|
|
snprintf(buf, L_BUF_SIZE, "set terminal latex; set output '%s'",
|
|
gplot->outname);
|
|
else /* gplot->outformat == GPLOT_X11 */
|
|
#ifndef COMPILER_MSVC
|
|
snprintf(buf, L_BUF_SIZE, "set terminal x11");
|
|
#else
|
|
snprintf(buf, L_BUF_SIZE, "set terminal windows");
|
|
#endif /* COMPILER_MSVC */
|
|
sarrayAddString(gplot->cmddata, buf, L_COPY);
|
|
|
|
if (gplot->scaling == GPLOT_LOG_SCALE_X ||
|
|
gplot->scaling == GPLOT_LOG_SCALE_X_Y) {
|
|
snprintf(buf, L_BUF_SIZE, "set logscale x");
|
|
sarrayAddString(gplot->cmddata, buf, L_COPY);
|
|
}
|
|
if (gplot->scaling == GPLOT_LOG_SCALE_Y ||
|
|
gplot->scaling == GPLOT_LOG_SCALE_X_Y) {
|
|
snprintf(buf, L_BUF_SIZE, "set logscale y");
|
|
sarrayAddString(gplot->cmddata, buf, L_COPY);
|
|
}
|
|
|
|
nplots = sarrayGetCount(gplot->datanames);
|
|
for (i = 0; i < nplots; i++) {
|
|
plottitle = sarrayGetString(gplot->plottitles, i, L_NOCOPY);
|
|
dataname = sarrayGetString(gplot->datanames, i, L_NOCOPY);
|
|
numaGetIValue(gplot->plotstyles, i, &plotstyle);
|
|
if (nplots == 1)
|
|
snprintf(buf, L_BUF_SIZE, "plot '%s' title '%s' %s",
|
|
dataname, plottitle, gplotstylenames[plotstyle]);
|
|
else {
|
|
if (i == 0)
|
|
snprintf(buf, L_BUF_SIZE, "plot '%s' title '%s' %s, \\",
|
|
dataname, plottitle, gplotstylenames[plotstyle]);
|
|
else if (i < nplots - 1)
|
|
snprintf(buf, L_BUF_SIZE, " '%s' title '%s' %s, \\",
|
|
dataname, plottitle, gplotstylenames[plotstyle]);
|
|
else
|
|
snprintf(buf, L_BUF_SIZE, " '%s' title '%s' %s",
|
|
dataname, plottitle, gplotstylenames[plotstyle]);
|
|
}
|
|
sarrayAddString(gplot->cmddata, buf, L_COPY);
|
|
}
|
|
|
|
/* Write command data to file */
|
|
cmdstr = sarrayToString(gplot->cmddata, 1);
|
|
if ((fp = fopen(gplot->cmdname, "w")) == NULL)
|
|
return ERROR_INT("cmd stream not opened", procName, 1);
|
|
fwrite(cmdstr, 1, strlen(cmdstr), fp);
|
|
fclose(fp);
|
|
FREE(cmdstr);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotGenDataFiles()
|
|
*
|
|
* Input: gplot
|
|
* Return: 0 if OK, 1 on error
|
|
*/
|
|
l_int32
|
|
gplotGenDataFiles(GPLOT *gplot)
|
|
{
|
|
char *plotdata, *dataname;
|
|
l_int32 i, nplots;
|
|
FILE *fp;
|
|
|
|
PROCNAME("gplotGenDataFiles");
|
|
|
|
if (!gplot)
|
|
return ERROR_INT("gplot not defined", procName, 1);
|
|
|
|
nplots = sarrayGetCount(gplot->datanames);
|
|
for (i = 0; i < nplots; i++) {
|
|
plotdata = sarrayGetString(gplot->plotdata, i, L_NOCOPY);
|
|
dataname = sarrayGetString(gplot->datanames, i, L_NOCOPY);
|
|
if ((fp = fopen(dataname, "w")) == NULL)
|
|
return ERROR_INT("datafile stream not opened", procName, 1);
|
|
fwrite(plotdata, 1, strlen(plotdata), fp);
|
|
fclose(fp);
|
|
}
|
|
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------*
|
|
* Quick and Dirty Plots *
|
|
*-----------------------------------------------------------------*/
|
|
/*!
|
|
* gplotSimple1()
|
|
*
|
|
* Input: na (numa; plot Y_VS_I)
|
|
* outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11,
|
|
* GPLOT_LATEX)
|
|
* outroot (root of output files)
|
|
* title (<optional>, can be NULL)
|
|
* Return: 0 if OK, 1 on error
|
|
*
|
|
* Notes:
|
|
* (1) This gives a line plot of a numa, where the array value
|
|
* is plotted vs the array index. The plot is generated
|
|
* in the specified output format; the title is optional.
|
|
* (2) When calling this function more than once, be sure the
|
|
* outroot strings are different; otherwise, you will
|
|
* overwrite the output files.
|
|
*/
|
|
l_int32
|
|
gplotSimple1(NUMA *na,
|
|
l_int32 outformat,
|
|
const char *outroot,
|
|
const char *title)
|
|
{
|
|
GPLOT *gplot;
|
|
|
|
PROCNAME("gplotSimple1");
|
|
|
|
if (!na)
|
|
return ERROR_INT("na not defined", procName, 1);
|
|
if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
|
|
outformat != GPLOT_EPS && outformat != GPLOT_X11 &&
|
|
outformat != GPLOT_LATEX)
|
|
return ERROR_INT("invalid outformat", procName, 1);
|
|
if (!outroot)
|
|
return ERROR_INT("outroot not specified", procName, 1);
|
|
|
|
if ((gplot = gplotCreate(outroot, outformat, title, NULL, NULL)) == 0)
|
|
return ERROR_INT("gplot not made", procName, 1);
|
|
gplotAddPlot(gplot, NULL, na, GPLOT_LINES, NULL);
|
|
gplotMakeOutput(gplot);
|
|
gplotDestroy(&gplot);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotSimple2()
|
|
*
|
|
* Input: na1 (numa; we plot Y_VS_I)
|
|
* na2 (ditto)
|
|
* outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11,
|
|
* GPLOT_LATEX)
|
|
* outroot (root of output files)
|
|
* title (<optional>)
|
|
* Return: 0 if OK, 1 on error
|
|
*
|
|
* Notes:
|
|
* (1) This gives a line plot of two numa, where the array values
|
|
* are each plotted vs the array index. The plot is generated
|
|
* in the specified output format; the title is optional.
|
|
* (2) When calling this function more than once, be sure the
|
|
* outroot strings are different; otherwise, you will
|
|
* overwrite the output files.
|
|
*/
|
|
l_int32
|
|
gplotSimple2(NUMA *na1,
|
|
NUMA *na2,
|
|
l_int32 outformat,
|
|
const char *outroot,
|
|
const char *title)
|
|
{
|
|
GPLOT *gplot;
|
|
|
|
PROCNAME("gplotSimple2");
|
|
|
|
if (!na1 || !na2)
|
|
return ERROR_INT("na1 and na2 not both defined", procName, 1);
|
|
if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
|
|
outformat != GPLOT_EPS && outformat != GPLOT_X11 &&
|
|
outformat != GPLOT_LATEX)
|
|
return ERROR_INT("invalid outformat", procName, 1);
|
|
if (!outroot)
|
|
return ERROR_INT("outroot not specified", procName, 1);
|
|
|
|
if ((gplot = gplotCreate(outroot, outformat, title, NULL, NULL)) == 0)
|
|
return ERROR_INT("gplot not made", procName, 1);
|
|
gplotAddPlot(gplot, NULL, na1, GPLOT_LINES, NULL);
|
|
gplotAddPlot(gplot, NULL, na2, GPLOT_LINES, NULL);
|
|
gplotMakeOutput(gplot);
|
|
gplotDestroy(&gplot);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotSimpleN()
|
|
*
|
|
* Input: naa (numaa; we plot Y_VS_I for each numa)
|
|
* outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11,
|
|
* GPLOT_LATEX)
|
|
* outroot (root of output files)
|
|
* title (<optional>)
|
|
* Return: 0 if OK, 1 on error
|
|
*
|
|
* Notes:
|
|
* (1) This gives a line plot of all numas in a numaa (array of numa),
|
|
* where the array values are each plotted vs the array index.
|
|
* The plot is generated in the specified output format;
|
|
* the title is optional.
|
|
* (2) When calling this function more than once, be sure the
|
|
* outroot strings are different; otherwise, you will
|
|
* overwrite the output files.
|
|
*/
|
|
l_int32
|
|
gplotSimpleN(NUMAA *naa,
|
|
l_int32 outformat,
|
|
const char *outroot,
|
|
const char *title)
|
|
{
|
|
l_int32 i, n;
|
|
GPLOT *gplot;
|
|
NUMA *na;
|
|
|
|
PROCNAME("gplotSimpleN");
|
|
|
|
if (!naa)
|
|
return ERROR_INT("naa not defined", procName, 1);
|
|
if ((n = numaaGetCount(naa)) == 0)
|
|
return ERROR_INT("no numa in array", procName, 1);
|
|
if (outformat != GPLOT_PNG && outformat != GPLOT_PS &&
|
|
outformat != GPLOT_EPS && outformat != GPLOT_X11 &&
|
|
outformat != GPLOT_LATEX)
|
|
return ERROR_INT("invalid outformat", procName, 1);
|
|
if (!outroot)
|
|
return ERROR_INT("outroot not specified", procName, 1);
|
|
|
|
if ((gplot = gplotCreate(outroot, outformat, title, NULL, NULL)) == 0)
|
|
return ERROR_INT("gplot not made", procName, 1);
|
|
for (i = 0; i < n; i++) {
|
|
na = numaaGetNuma(naa, i, L_CLONE);
|
|
gplotAddPlot(gplot, NULL, na, GPLOT_LINES, NULL);
|
|
numaDestroy(&na);
|
|
}
|
|
gplotMakeOutput(gplot);
|
|
gplotDestroy(&gplot);
|
|
return 0;
|
|
}
|
|
|
|
|
|
/*-----------------------------------------------------------------*
|
|
* Serialize for I/O *
|
|
*-----------------------------------------------------------------*/
|
|
/*!
|
|
* gplotRead()
|
|
*
|
|
* Input: filename
|
|
* Return: gplot, or NULL on error
|
|
*/
|
|
GPLOT *
|
|
gplotRead(const char *filename)
|
|
{
|
|
char buf[L_BUF_SIZE];
|
|
char *rootname, *title, *xlabel, *ylabel;
|
|
l_int32 outformat, ret, version;
|
|
FILE *fp;
|
|
GPLOT *gplot;
|
|
|
|
PROCNAME("gplotRead");
|
|
|
|
if (!filename)
|
|
return (GPLOT *)ERROR_PTR("filename not defined", procName, NULL);
|
|
|
|
if ((fp = fopen(filename, "r")) == NULL)
|
|
return (GPLOT *)ERROR_PTR("stream not opened", procName, NULL);
|
|
|
|
ret = fscanf(fp, "Gplot Version %d\n", &version);
|
|
if (ret != 1) {
|
|
fclose(fp);
|
|
return (GPLOT *)ERROR_PTR("not a gplot file", procName, NULL);
|
|
}
|
|
if (version != GPLOT_VERSION_NUMBER) {
|
|
fclose(fp);
|
|
return (GPLOT *)ERROR_PTR("invalid gplot version", procName, NULL);
|
|
}
|
|
|
|
fscanf(fp, "Rootname: %s\n", buf);
|
|
rootname = stringNew(buf);
|
|
fscanf(fp, "Output format: %d\n", &outformat);
|
|
fgets(buf, L_BUF_SIZE, fp); /* Title: ... */
|
|
title = stringNew(buf + 7);
|
|
title[strlen(title) - 1] = '\0';
|
|
fgets(buf, L_BUF_SIZE, fp); /* X axis label: ... */
|
|
xlabel = stringNew(buf + 14);
|
|
xlabel[strlen(xlabel) - 1] = '\0';
|
|
fgets(buf, L_BUF_SIZE, fp); /* Y axis label: ... */
|
|
ylabel = stringNew(buf + 14);
|
|
ylabel[strlen(ylabel) - 1] = '\0';
|
|
|
|
if (!(gplot = gplotCreate(rootname, outformat, title, xlabel, ylabel))) {
|
|
fclose(fp);
|
|
return (GPLOT *)ERROR_PTR("gplot not made", procName, NULL);
|
|
}
|
|
FREE(rootname);
|
|
FREE(title);
|
|
FREE(xlabel);
|
|
FREE(ylabel);
|
|
sarrayDestroy(&gplot->cmddata);
|
|
sarrayDestroy(&gplot->datanames);
|
|
sarrayDestroy(&gplot->plotdata);
|
|
sarrayDestroy(&gplot->plottitles);
|
|
numaDestroy(&gplot->plotstyles);
|
|
|
|
fscanf(fp, "Commandfile name: %s\n", buf);
|
|
stringReplace(&gplot->cmdname, buf);
|
|
fscanf(fp, "\nCommandfile data:");
|
|
gplot->cmddata = sarrayReadStream(fp);
|
|
fscanf(fp, "\nDatafile names:");
|
|
gplot->datanames = sarrayReadStream(fp);
|
|
fscanf(fp, "\nPlot data:");
|
|
gplot->plotdata = sarrayReadStream(fp);
|
|
fscanf(fp, "\nPlot titles:");
|
|
gplot->plottitles = sarrayReadStream(fp);
|
|
fscanf(fp, "\nPlot styles:");
|
|
gplot->plotstyles = numaReadStream(fp);
|
|
|
|
fscanf(fp, "Number of plots: %d\n", &gplot->nplots);
|
|
fscanf(fp, "Output file name: %s\n", buf);
|
|
stringReplace(&gplot->outname, buf);
|
|
fscanf(fp, "Axis scaling: %d\n", &gplot->scaling);
|
|
|
|
fclose(fp);
|
|
return gplot;
|
|
}
|
|
|
|
|
|
/*!
|
|
* gplotWrite()
|
|
*
|
|
* Input: filename
|
|
* gplot
|
|
* Return: 0 if OK; 1 on error
|
|
*/
|
|
l_int32
|
|
gplotWrite(const char *filename,
|
|
GPLOT *gplot)
|
|
{
|
|
FILE *fp;
|
|
|
|
PROCNAME("gplotWrite");
|
|
|
|
if (!filename)
|
|
return ERROR_INT("filename not defined", procName, 1);
|
|
if (!gplot)
|
|
return ERROR_INT("gplot not defined", procName, 1);
|
|
|
|
if ((fp = fopen(filename, "w")) == NULL)
|
|
return ERROR_INT("stream not opened", procName, 1);
|
|
|
|
fprintf(fp, "Gplot Version %d\n", GPLOT_VERSION_NUMBER);
|
|
fprintf(fp, "Rootname: %s\n", gplot->rootname);
|
|
fprintf(fp, "Output format: %d\n", gplot->outformat);
|
|
fprintf(fp, "Title: %s\n", gplot->title);
|
|
fprintf(fp, "X axis label: %s\n", gplot->xlabel);
|
|
fprintf(fp, "Y axis label: %s\n", gplot->ylabel);
|
|
|
|
fprintf(fp, "Commandfile name: %s\n", gplot->cmdname);
|
|
fprintf(fp, "\nCommandfile data:");
|
|
sarrayWriteStream(fp, gplot->cmddata);
|
|
fprintf(fp, "\nDatafile names:");
|
|
sarrayWriteStream(fp, gplot->datanames);
|
|
fprintf(fp, "\nPlot data:");
|
|
sarrayWriteStream(fp, gplot->plotdata);
|
|
fprintf(fp, "\nPlot titles:");
|
|
sarrayWriteStream(fp, gplot->plottitles);
|
|
fprintf(fp, "\nPlot styles:");
|
|
numaWriteStream(fp, gplot->plotstyles);
|
|
|
|
fprintf(fp, "Number of plots: %d\n", gplot->nplots);
|
|
fprintf(fp, "Output file name: %s\n", gplot->outname);
|
|
fprintf(fp, "Axis scaling: %d\n", gplot->scaling);
|
|
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
|
|
|