Leptonica 1.68
C Image Processing Library
|
00001 /*====================================================================* 00002 - Copyright (C) 2001 Leptonica. All rights reserved. 00003 - This software is distributed in the hope that it will be 00004 - useful, but with NO WARRANTY OF ANY KIND. 00005 - No author or distributor accepts responsibility to anyone for the 00006 - consequences of using this software, or for whether it serves any 00007 - particular purpose or works at all, unless he or she says so in 00008 - writing. Everyone is granted permission to copy, modify and 00009 - redistribute this source code, for commercial or non-commercial 00010 - purposes, with the following restrictions: (1) the origin of this 00011 - source code must not be misrepresented; (2) modified versions must 00012 - be plainly marked as such; and (3) this notice may not be removed 00013 - or altered from any source or modified source distribution. 00014 *====================================================================*/ 00015 00016 /* 00017 * gplot.c 00018 * 00019 * Basic plotting functions 00020 * GPLOT *gplotCreate() 00021 * void gplotDestroy() 00022 * l_int32 gplotAddPlot() 00023 * l_int32 gplotSetScaling() 00024 * l_int32 gplotMakeOutput() 00025 * l_int32 gplotGenCommandFile() 00026 * l_int32 gplotGenDataFiles() 00027 * 00028 * Quick and dirty plots 00029 * l_int32 gplotSimple1() 00030 * l_int32 gplotSimple2() 00031 * l_int32 gplotSimpleN() 00032 * 00033 * Serialize for I/O 00034 * GPLOT *gplotRead() 00035 * l_int32 gplotWrite() 00036 * 00037 * 00038 * Utility for programmatic plotting using gnuplot 7.3.2 or later 00039 * Enabled: 00040 * - output to png (color), ps (mono), x11 (color), latex (mono) 00041 * - optional title for graph 00042 * - optional x and y axis labels 00043 * - multiple plots on one frame 00044 * - optional title for each plot on the frame 00045 * - optional log scaling on either or both axes 00046 * - choice of 5 plot styles for each plot 00047 * - choice of 2 plot modes, either using one input array 00048 * (Y vs index) or two input arrays (Y vs X). This 00049 * choice is made implicitly depending on the number of 00050 * input arrays. 00051 * 00052 * Usage: 00053 * gplotCreate() initializes for plotting 00054 * gplotAddPlot() for each plot on the frame 00055 * gplotMakeOutput() to generate all output files and run gnuplot 00056 * gplotDestroy() to clean up 00057 * 00058 * Example of use: 00059 * gplot = gplotCreate("tempskew", GPLOT_PNG, "Skew score vs angle", 00060 * "angle (deg)", "score"); 00061 * gplotAddPlot(gplot, natheta, nascore1, GPLOT_LINES, "plot 1"); 00062 * gplotAddPlot(gplot, natheta, nascore2, GPLOT_POINTS, "plot 2"); 00063 * gplotSetScaling(gplot, GPLOT_LOG_SCALE_Y); 00064 * gplotMakeOutput(gplot); 00065 * gplotDestroy(&gplot); 00066 * 00067 * Note for output to GPLOT_LATEX: 00068 * This creates latex output of the plot, named <rootname>.tex. 00069 * It needs to be placed in a latex file <latexname>.tex 00070 * that precedes the plot output with, at a minimum: 00071 * \documentclass{article} 00072 * \begin{document} 00073 * and ends with 00074 * \end{document} 00075 * You can then generate a dvi file <latexname>.dvi using 00076 * latex <latexname>.tex 00077 * and a PostScript file <psname>.ps from that using 00078 * dvips -o <psname>.ps <latexname>.dvi 00079 */ 00080 00081 #include <string.h> 00082 #include "allheaders.h" 00083 00084 /* MS VC++ can't handle array initialization with static consts ! */ 00085 #define L_BUF_SIZE 512 00086 #define MAX_NUM_GPLOTS 40 00087 00088 const char *gplotstylenames[] = {"with lines", 00089 "with points", 00090 "with impulses", 00091 "with linespoints", 00092 "with dots"}; 00093 const char *gplotfilestyles[] = {"LINES", 00094 "POINTS", 00095 "IMPULSES", 00096 "LINESPOINTS", 00097 "DOTS"}; 00098 const char *gplotfileoutputs[] = {"", 00099 "PNG", 00100 "PS", 00101 "EPS", 00102 "X11", 00103 "LATEX"}; 00104 00105 00106 /*-----------------------------------------------------------------* 00107 * Basic Plotting Functions * 00108 *-----------------------------------------------------------------*/ 00109 /*! 00110 * gplotCreate() 00111 * 00112 * Input: rootname (root for all output files) 00113 * outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11, 00114 * GPLOT_LATEX) 00115 * title (<optional> overall title) 00116 * xlabel (<optional> x axis label) 00117 * ylabel (<optional> y axis label) 00118 * Return: gplot, or null on error 00119 * 00120 * Notes: 00121 * (1) This initializes the plot. 00122 * (2) The 'title', 'xlabel' and 'ylabel' strings can have spaces, 00123 * double quotes and backquotes, but not single quotes. 00124 */ 00125 GPLOT * 00126 gplotCreate(const char *rootname, 00127 l_int32 outformat, 00128 const char *title, 00129 const char *xlabel, 00130 const char *ylabel) 00131 { 00132 char *newroot; 00133 char buf[L_BUF_SIZE]; 00134 GPLOT *gplot; 00135 00136 PROCNAME("gplotCreate"); 00137 00138 if (!rootname) 00139 return (GPLOT *)ERROR_PTR("rootname not defined", procName, NULL); 00140 if (outformat != GPLOT_PNG && outformat != GPLOT_PS && 00141 outformat != GPLOT_EPS && outformat != GPLOT_X11 && 00142 outformat != GPLOT_LATEX) 00143 return (GPLOT *)ERROR_PTR("outformat invalid", procName, NULL); 00144 00145 if ((gplot = (GPLOT *)CALLOC(1, sizeof(GPLOT))) == NULL) 00146 return (GPLOT *)ERROR_PTR("gplot not made", procName, NULL); 00147 gplot->cmddata = sarrayCreate(0); 00148 gplot->datanames = sarrayCreate(0); 00149 gplot->plotdata = sarrayCreate(0); 00150 gplot->plottitles = sarrayCreate(0); 00151 gplot->plotstyles = numaCreate(0); 00152 00153 /* Save title, labels, rootname, outformat, cmdname, outname */ 00154 newroot = genPathname(rootname, NULL); /* remove '/tmp' on windows */ 00155 gplot->rootname = newroot; 00156 gplot->outformat = outformat; 00157 snprintf(buf, L_BUF_SIZE, "%s.cmd", newroot); 00158 gplot->cmdname = stringNew(buf); 00159 if (outformat == GPLOT_PNG) 00160 snprintf(buf, L_BUF_SIZE, "%s.png", newroot); 00161 else if (outformat == GPLOT_PS) 00162 snprintf(buf, L_BUF_SIZE, "%s.ps", newroot); 00163 else if (outformat == GPLOT_EPS) 00164 snprintf(buf, L_BUF_SIZE, "%s.eps", newroot); 00165 else if (outformat == GPLOT_LATEX) 00166 snprintf(buf, L_BUF_SIZE, "%s.tex", newroot); 00167 else /* outformat == GPLOT_X11 */ 00168 buf[0] = '\0'; 00169 gplot->outname = stringNew(buf); 00170 if (title) gplot->title = stringNew(title); 00171 if (xlabel) gplot->xlabel = stringNew(xlabel); 00172 if (ylabel) gplot->ylabel = stringNew(ylabel); 00173 00174 return gplot; 00175 } 00176 00177 00178 /*! 00179 * gplotDestroy() 00180 * 00181 * Input: &gplot (<to be nulled>) 00182 * Return: void 00183 */ 00184 void 00185 gplotDestroy(GPLOT **pgplot) 00186 { 00187 GPLOT *gplot; 00188 00189 PROCNAME("gplotDestroy"); 00190 00191 if (pgplot == NULL) { 00192 L_WARNING("ptr address is null!", procName); 00193 return; 00194 } 00195 00196 if ((gplot = *pgplot) == NULL) 00197 return; 00198 00199 FREE(gplot->rootname); 00200 FREE(gplot->cmdname); 00201 sarrayDestroy(&gplot->cmddata); 00202 sarrayDestroy(&gplot->datanames); 00203 sarrayDestroy(&gplot->plotdata); 00204 sarrayDestroy(&gplot->plottitles); 00205 numaDestroy(&gplot->plotstyles); 00206 FREE(gplot->outname); 00207 if (gplot->title) 00208 FREE(gplot->title); 00209 if (gplot->xlabel) 00210 FREE(gplot->xlabel); 00211 if (gplot->ylabel) 00212 FREE(gplot->ylabel); 00213 00214 FREE(gplot); 00215 *pgplot = NULL; 00216 return; 00217 } 00218 00219 00220 /*! 00221 * gplotAddPlot() 00222 * 00223 * Input: gplot 00224 * nax (<optional> numa: set to null for Y_VS_I; 00225 * required for Y_VS_X) 00226 * nay (numa: required for both Y_VS_I and Y_VS_X) 00227 * plotstyle (GPLOT_LINES, GPLOT_POINTS, GPLOT_IMPULSES, 00228 * GPLOT_LINESPOINTS, GPLOT_DOTS) 00229 * plottitle (<optional> title for individual plot) 00230 * Return: 0 if OK, 1 on error 00231 * 00232 * Notes: 00233 * (1) There are 2 options for (x,y) values: 00234 * o To plot an array vs the index, set nax = NULL. 00235 * o To plot one array vs another, use both nax and nay. 00236 * (2) If nax is defined, it must be the same size as nay. 00237 * (3) The 'plottitle' string can have spaces, double 00238 * quotes and backquotes, but not single quotes. 00239 */ 00240 l_int32 00241 gplotAddPlot(GPLOT *gplot, 00242 NUMA *nax, 00243 NUMA *nay, 00244 l_int32 plotstyle, 00245 const char *plottitle) 00246 { 00247 char buf[L_BUF_SIZE]; 00248 char emptystring[] = ""; 00249 char *datastr, *title; 00250 l_int32 n, i; 00251 l_float32 valx, valy, startx, delx; 00252 SARRAY *sa; 00253 00254 PROCNAME("gplotAddPlot"); 00255 00256 if (!gplot) 00257 return ERROR_INT("gplot not defined", procName, 1); 00258 if (!nay) 00259 return ERROR_INT("nay not defined", procName, 1); 00260 if (plotstyle != GPLOT_LINES && plotstyle != GPLOT_POINTS && 00261 plotstyle != GPLOT_IMPULSES && plotstyle != GPLOT_LINESPOINTS && 00262 plotstyle != GPLOT_DOTS) 00263 return ERROR_INT("invalid plotstyle", procName, 1); 00264 00265 n = numaGetCount(nay); 00266 numaGetXParameters(nay, &startx, &delx); 00267 if (nax) { 00268 if (n != numaGetCount(nax)) 00269 return ERROR_INT("nax and nay sizes differ", procName, 1); 00270 } 00271 00272 /* Save plotstyle and plottitle */ 00273 numaAddNumber(gplot->plotstyles, plotstyle); 00274 if (plottitle) { 00275 title = stringNew(plottitle); 00276 sarrayAddString(gplot->plottitles, title, L_INSERT); 00277 } 00278 else 00279 sarrayAddString(gplot->plottitles, emptystring, L_COPY); 00280 00281 /* Generate and save data filename */ 00282 gplot->nplots++; 00283 snprintf(buf, L_BUF_SIZE, "%s.data.%d", gplot->rootname, gplot->nplots); 00284 sarrayAddString(gplot->datanames, buf, L_COPY); 00285 00286 /* Generate data and save as a string */ 00287 sa = sarrayCreate(n); 00288 for (i = 0; i < n; i++) { 00289 if (nax) 00290 numaGetFValue(nax, i, &valx); 00291 else 00292 valx = startx + i * delx; 00293 numaGetFValue(nay, i, &valy); 00294 snprintf(buf, L_BUF_SIZE, "%f %f\n", valx, valy); 00295 sarrayAddString(sa, buf, L_COPY); 00296 } 00297 datastr = sarrayToString(sa, 0); 00298 sarrayAddString(gplot->plotdata, datastr, L_INSERT); 00299 sarrayDestroy(&sa); 00300 00301 return 0; 00302 } 00303 00304 00305 /*! 00306 * gplotSetScaling() 00307 * 00308 * Input: gplot 00309 * scaling (GPLOT_LINEAR_SCALE, GPLOT_LOG_SCALE_X, 00310 * GPLOT_LOG_SCALE_Y, GPLOT_LOG_SCALE_X_Y) 00311 * Return: 0 if OK; 1 on error 00312 * 00313 * Notes: 00314 * (1) By default, the x and y axis scaling is linear. 00315 * (2) Call this function to set semi-log or log-log scaling. 00316 */ 00317 l_int32 00318 gplotSetScaling(GPLOT *gplot, 00319 l_int32 scaling) 00320 { 00321 PROCNAME("gplotSetScaling"); 00322 00323 if (!gplot) 00324 return ERROR_INT("gplot not defined", procName, 1); 00325 if (scaling != GPLOT_LINEAR_SCALE && 00326 scaling != GPLOT_LOG_SCALE_X && 00327 scaling != GPLOT_LOG_SCALE_Y && 00328 scaling != GPLOT_LOG_SCALE_X_Y) 00329 return ERROR_INT("invalid gplot scaling", procName, 1); 00330 gplot->scaling = scaling; 00331 return 0; 00332 } 00333 00334 00335 /*! 00336 * gplotMakeOutput() 00337 * 00338 * Input: gplot 00339 * Return: 0 if OK; 1 on error 00340 * 00341 * Notes: 00342 * (1) This uses gplot and the new arrays to add a plot 00343 * to the output, by writing a new data file and appending 00344 * the appropriate plot commands to the command file. 00345 * (2) The gnuplot program for windows is wgnuplot.exe. The 00346 * standard gp426win32 distribution does not have a X11 terminal. 00347 */ 00348 l_int32 00349 gplotMakeOutput(GPLOT *gplot) 00350 { 00351 char buf[L_BUF_SIZE]; 00352 l_int32 ignore; 00353 00354 PROCNAME("gplotMakeOutput"); 00355 00356 if (!gplot) 00357 return ERROR_INT("gplot not defined", procName, 1); 00358 00359 gplotGenCommandFile(gplot); 00360 gplotGenDataFiles(gplot); 00361 00362 #ifndef _WIN32 00363 if (gplot->outformat != GPLOT_X11) 00364 snprintf(buf, L_BUF_SIZE, "gnuplot %s &", gplot->cmdname); 00365 else 00366 snprintf(buf, L_BUF_SIZE, 00367 "gnuplot -persist -geometry +10+10 %s &", gplot->cmdname); 00368 #else 00369 if (gplot->outformat != GPLOT_X11) 00370 snprintf(buf, L_BUF_SIZE, "wgnuplot %s", gplot->cmdname); 00371 else 00372 snprintf(buf, L_BUF_SIZE, 00373 "wgnuplot -persist %s", gplot->cmdname); 00374 #endif /* _WIN32 */ 00375 ignore = system(buf); 00376 return 0; 00377 } 00378 00379 00380 /*! 00381 * gplotGenCommandFile() 00382 * 00383 * Input: gplot 00384 * Return: 0 if OK, 1 on error 00385 */ 00386 l_int32 00387 gplotGenCommandFile(GPLOT *gplot) 00388 { 00389 char buf[L_BUF_SIZE]; 00390 char *cmdstr, *plottitle, *dataname; 00391 l_int32 i, plotstyle, nplots; 00392 FILE *fp; 00393 00394 PROCNAME("gplotGenCommandFile"); 00395 00396 if (!gplot) 00397 return ERROR_INT("gplot not defined", procName, 1); 00398 00399 /* Remove any previous command data */ 00400 sarrayClear(gplot->cmddata); 00401 00402 /* Generate command data instructions */ 00403 if (gplot->title) { /* set title */ 00404 snprintf(buf, L_BUF_SIZE, "set title '%s'", gplot->title); 00405 sarrayAddString(gplot->cmddata, buf, L_COPY); 00406 } 00407 if (gplot->xlabel) { /* set xlabel */ 00408 snprintf(buf, L_BUF_SIZE, "set xlabel '%s'", gplot->xlabel); 00409 sarrayAddString(gplot->cmddata, buf, L_COPY); 00410 } 00411 if (gplot->ylabel) { /* set ylabel */ 00412 snprintf(buf, L_BUF_SIZE, "set ylabel '%s'", gplot->ylabel); 00413 sarrayAddString(gplot->cmddata, buf, L_COPY); 00414 } 00415 00416 if (gplot->outformat == GPLOT_PNG) /* set terminal type and output */ 00417 snprintf(buf, L_BUF_SIZE, "set terminal png; set output '%s'", 00418 gplot->outname); 00419 else if (gplot->outformat == GPLOT_PS) 00420 snprintf(buf, L_BUF_SIZE, "set terminal postscript; set output '%s'", 00421 gplot->outname); 00422 else if (gplot->outformat == GPLOT_EPS) 00423 snprintf(buf, L_BUF_SIZE, 00424 "set terminal postscript eps; set output '%s'", 00425 gplot->outname); 00426 else if (gplot->outformat == GPLOT_LATEX) 00427 snprintf(buf, L_BUF_SIZE, "set terminal latex; set output '%s'", 00428 gplot->outname); 00429 else /* gplot->outformat == GPLOT_X11 */ 00430 #ifndef _WIN32 00431 snprintf(buf, L_BUF_SIZE, "set terminal x11"); 00432 #else 00433 snprintf(buf, L_BUF_SIZE, "set terminal windows"); 00434 #endif /* _WIN32 */ 00435 sarrayAddString(gplot->cmddata, buf, L_COPY); 00436 00437 if (gplot->scaling == GPLOT_LOG_SCALE_X || 00438 gplot->scaling == GPLOT_LOG_SCALE_X_Y) { 00439 snprintf(buf, L_BUF_SIZE, "set logscale x"); 00440 sarrayAddString(gplot->cmddata, buf, L_COPY); 00441 } 00442 if (gplot->scaling == GPLOT_LOG_SCALE_Y || 00443 gplot->scaling == GPLOT_LOG_SCALE_X_Y) { 00444 snprintf(buf, L_BUF_SIZE, "set logscale y"); 00445 sarrayAddString(gplot->cmddata, buf, L_COPY); 00446 } 00447 00448 nplots = sarrayGetCount(gplot->datanames); 00449 for (i = 0; i < nplots; i++) { 00450 plottitle = sarrayGetString(gplot->plottitles, i, L_NOCOPY); 00451 dataname = sarrayGetString(gplot->datanames, i, L_NOCOPY); 00452 numaGetIValue(gplot->plotstyles, i, &plotstyle); 00453 if (nplots == 1) 00454 snprintf(buf, L_BUF_SIZE, "plot '%s' title '%s' %s", 00455 dataname, plottitle, gplotstylenames[plotstyle]); 00456 else { 00457 if (i == 0) 00458 snprintf(buf, L_BUF_SIZE, "plot '%s' title '%s' %s, \\", 00459 dataname, plottitle, gplotstylenames[plotstyle]); 00460 else if (i < nplots - 1) 00461 snprintf(buf, L_BUF_SIZE, " '%s' title '%s' %s, \\", 00462 dataname, plottitle, gplotstylenames[plotstyle]); 00463 else 00464 snprintf(buf, L_BUF_SIZE, " '%s' title '%s' %s", 00465 dataname, plottitle, gplotstylenames[plotstyle]); 00466 } 00467 sarrayAddString(gplot->cmddata, buf, L_COPY); 00468 } 00469 00470 /* Write command data to file */ 00471 cmdstr = sarrayToString(gplot->cmddata, 1); 00472 if ((fp = fopenWriteStream(gplot->cmdname, "w")) == NULL) 00473 return ERROR_INT("cmd stream not opened", procName, 1); 00474 fwrite(cmdstr, 1, strlen(cmdstr), fp); 00475 fclose(fp); 00476 FREE(cmdstr); 00477 return 0; 00478 } 00479 00480 00481 /*! 00482 * gplotGenDataFiles() 00483 * 00484 * Input: gplot 00485 * Return: 0 if OK, 1 on error 00486 */ 00487 l_int32 00488 gplotGenDataFiles(GPLOT *gplot) 00489 { 00490 char *plotdata, *dataname; 00491 l_int32 i, nplots; 00492 FILE *fp; 00493 00494 PROCNAME("gplotGenDataFiles"); 00495 00496 if (!gplot) 00497 return ERROR_INT("gplot not defined", procName, 1); 00498 00499 nplots = sarrayGetCount(gplot->datanames); 00500 for (i = 0; i < nplots; i++) { 00501 plotdata = sarrayGetString(gplot->plotdata, i, L_NOCOPY); 00502 dataname = sarrayGetString(gplot->datanames, i, L_NOCOPY); 00503 if ((fp = fopenWriteStream(dataname, "w")) == NULL) 00504 return ERROR_INT("datafile stream not opened", procName, 1); 00505 fwrite(plotdata, 1, strlen(plotdata), fp); 00506 fclose(fp); 00507 } 00508 00509 return 0; 00510 } 00511 00512 00513 /*-----------------------------------------------------------------* 00514 * Quick and Dirty Plots * 00515 *-----------------------------------------------------------------*/ 00516 /*! 00517 * gplotSimple1() 00518 * 00519 * Input: na (numa; plot Y_VS_I) 00520 * outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11, 00521 * GPLOT_LATEX) 00522 * outroot (root of output files) 00523 * title (<optional>, can be NULL) 00524 * Return: 0 if OK, 1 on error 00525 * 00526 * Notes: 00527 * (1) This gives a line plot of a numa, where the array value 00528 * is plotted vs the array index. The plot is generated 00529 * in the specified output format; the title is optional. 00530 * (2) When calling this function more than once, be sure the 00531 * outroot strings are different; otherwise, you will 00532 * overwrite the output files. 00533 */ 00534 l_int32 00535 gplotSimple1(NUMA *na, 00536 l_int32 outformat, 00537 const char *outroot, 00538 const char *title) 00539 { 00540 GPLOT *gplot; 00541 00542 PROCNAME("gplotSimple1"); 00543 00544 if (!na) 00545 return ERROR_INT("na not defined", procName, 1); 00546 if (outformat != GPLOT_PNG && outformat != GPLOT_PS && 00547 outformat != GPLOT_EPS && outformat != GPLOT_X11 && 00548 outformat != GPLOT_LATEX) 00549 return ERROR_INT("invalid outformat", procName, 1); 00550 if (!outroot) 00551 return ERROR_INT("outroot not specified", procName, 1); 00552 00553 if ((gplot = gplotCreate(outroot, outformat, title, NULL, NULL)) == 0) 00554 return ERROR_INT("gplot not made", procName, 1); 00555 gplotAddPlot(gplot, NULL, na, GPLOT_LINES, NULL); 00556 gplotMakeOutput(gplot); 00557 gplotDestroy(&gplot); 00558 return 0; 00559 } 00560 00561 00562 /*! 00563 * gplotSimple2() 00564 * 00565 * Input: na1 (numa; we plot Y_VS_I) 00566 * na2 (ditto) 00567 * outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11, 00568 * GPLOT_LATEX) 00569 * outroot (root of output files) 00570 * title (<optional>) 00571 * Return: 0 if OK, 1 on error 00572 * 00573 * Notes: 00574 * (1) This gives a line plot of two numa, where the array values 00575 * are each plotted vs the array index. The plot is generated 00576 * in the specified output format; the title is optional. 00577 * (2) When calling this function more than once, be sure the 00578 * outroot strings are different; otherwise, you will 00579 * overwrite the output files. 00580 */ 00581 l_int32 00582 gplotSimple2(NUMA *na1, 00583 NUMA *na2, 00584 l_int32 outformat, 00585 const char *outroot, 00586 const char *title) 00587 { 00588 GPLOT *gplot; 00589 00590 PROCNAME("gplotSimple2"); 00591 00592 if (!na1 || !na2) 00593 return ERROR_INT("na1 and na2 not both defined", procName, 1); 00594 if (outformat != GPLOT_PNG && outformat != GPLOT_PS && 00595 outformat != GPLOT_EPS && outformat != GPLOT_X11 && 00596 outformat != GPLOT_LATEX) 00597 return ERROR_INT("invalid outformat", procName, 1); 00598 if (!outroot) 00599 return ERROR_INT("outroot not specified", procName, 1); 00600 00601 if ((gplot = gplotCreate(outroot, outformat, title, NULL, NULL)) == 0) 00602 return ERROR_INT("gplot not made", procName, 1); 00603 gplotAddPlot(gplot, NULL, na1, GPLOT_LINES, NULL); 00604 gplotAddPlot(gplot, NULL, na2, GPLOT_LINES, NULL); 00605 gplotMakeOutput(gplot); 00606 gplotDestroy(&gplot); 00607 return 0; 00608 } 00609 00610 00611 /*! 00612 * gplotSimpleN() 00613 * 00614 * Input: naa (numaa; we plot Y_VS_I for each numa) 00615 * outformat (GPLOT_PNG, GPLOT_PS, GPLOT_EPS, GPLOT_X11, 00616 * GPLOT_LATEX) 00617 * outroot (root of output files) 00618 * title (<optional>) 00619 * Return: 0 if OK, 1 on error 00620 * 00621 * Notes: 00622 * (1) This gives a line plot of all numas in a numaa (array of numa), 00623 * where the array values are each plotted vs the array index. 00624 * The plot is generated in the specified output format; 00625 * the title is optional. 00626 * (2) When calling this function more than once, be sure the 00627 * outroot strings are different; otherwise, you will 00628 * overwrite the output files. 00629 */ 00630 l_int32 00631 gplotSimpleN(NUMAA *naa, 00632 l_int32 outformat, 00633 const char *outroot, 00634 const char *title) 00635 { 00636 l_int32 i, n; 00637 GPLOT *gplot; 00638 NUMA *na; 00639 00640 PROCNAME("gplotSimpleN"); 00641 00642 if (!naa) 00643 return ERROR_INT("naa not defined", procName, 1); 00644 if ((n = numaaGetCount(naa)) == 0) 00645 return ERROR_INT("no numa in array", procName, 1); 00646 if (outformat != GPLOT_PNG && outformat != GPLOT_PS && 00647 outformat != GPLOT_EPS && outformat != GPLOT_X11 && 00648 outformat != GPLOT_LATEX) 00649 return ERROR_INT("invalid outformat", procName, 1); 00650 if (!outroot) 00651 return ERROR_INT("outroot not specified", procName, 1); 00652 00653 if ((gplot = gplotCreate(outroot, outformat, title, NULL, NULL)) == 0) 00654 return ERROR_INT("gplot not made", procName, 1); 00655 for (i = 0; i < n; i++) { 00656 na = numaaGetNuma(naa, i, L_CLONE); 00657 gplotAddPlot(gplot, NULL, na, GPLOT_LINES, NULL); 00658 numaDestroy(&na); 00659 } 00660 gplotMakeOutput(gplot); 00661 gplotDestroy(&gplot); 00662 return 0; 00663 } 00664 00665 00666 /*-----------------------------------------------------------------* 00667 * Serialize for I/O * 00668 *-----------------------------------------------------------------*/ 00669 /*! 00670 * gplotRead() 00671 * 00672 * Input: filename 00673 * Return: gplot, or NULL on error 00674 */ 00675 GPLOT * 00676 gplotRead(const char *filename) 00677 { 00678 char buf[L_BUF_SIZE]; 00679 char *rootname, *title, *xlabel, *ylabel, *ignores; 00680 l_int32 outformat, ret, version, ignore; 00681 FILE *fp; 00682 GPLOT *gplot; 00683 00684 PROCNAME("gplotRead"); 00685 00686 if (!filename) 00687 return (GPLOT *)ERROR_PTR("filename not defined", procName, NULL); 00688 00689 if ((fp = fopenReadStream(filename)) == NULL) 00690 return (GPLOT *)ERROR_PTR("stream not opened", procName, NULL); 00691 00692 ret = fscanf(fp, "Gplot Version %d\n", &version); 00693 if (ret != 1) { 00694 fclose(fp); 00695 return (GPLOT *)ERROR_PTR("not a gplot file", procName, NULL); 00696 } 00697 if (version != GPLOT_VERSION_NUMBER) { 00698 fclose(fp); 00699 return (GPLOT *)ERROR_PTR("invalid gplot version", procName, NULL); 00700 } 00701 00702 ignore = fscanf(fp, "Rootname: %s\n", buf); 00703 rootname = stringNew(buf); 00704 ignore = fscanf(fp, "Output format: %d\n", &outformat); 00705 ignores = fgets(buf, L_BUF_SIZE, fp); /* Title: ... */ 00706 title = stringNew(buf + 7); 00707 title[strlen(title) - 1] = '\0'; 00708 ignores = fgets(buf, L_BUF_SIZE, fp); /* X axis label: ... */ 00709 xlabel = stringNew(buf + 14); 00710 xlabel[strlen(xlabel) - 1] = '\0'; 00711 ignores = fgets(buf, L_BUF_SIZE, fp); /* Y axis label: ... */ 00712 ylabel = stringNew(buf + 14); 00713 ylabel[strlen(ylabel) - 1] = '\0'; 00714 00715 if (!(gplot = gplotCreate(rootname, outformat, title, xlabel, ylabel))) { 00716 fclose(fp); 00717 return (GPLOT *)ERROR_PTR("gplot not made", procName, NULL); 00718 } 00719 FREE(rootname); 00720 FREE(title); 00721 FREE(xlabel); 00722 FREE(ylabel); 00723 sarrayDestroy(&gplot->cmddata); 00724 sarrayDestroy(&gplot->datanames); 00725 sarrayDestroy(&gplot->plotdata); 00726 sarrayDestroy(&gplot->plottitles); 00727 numaDestroy(&gplot->plotstyles); 00728 00729 ignore = fscanf(fp, "Commandfile name: %s\n", buf); 00730 stringReplace(&gplot->cmdname, buf); 00731 ignore = fscanf(fp, "\nCommandfile data:"); 00732 gplot->cmddata = sarrayReadStream(fp); 00733 ignore = fscanf(fp, "\nDatafile names:"); 00734 gplot->datanames = sarrayReadStream(fp); 00735 ignore = fscanf(fp, "\nPlot data:"); 00736 gplot->plotdata = sarrayReadStream(fp); 00737 ignore = fscanf(fp, "\nPlot titles:"); 00738 gplot->plottitles = sarrayReadStream(fp); 00739 ignore = fscanf(fp, "\nPlot styles:"); 00740 gplot->plotstyles = numaReadStream(fp); 00741 00742 ignore = fscanf(fp, "Number of plots: %d\n", &gplot->nplots); 00743 ignore = fscanf(fp, "Output file name: %s\n", buf); 00744 stringReplace(&gplot->outname, buf); 00745 ignore = fscanf(fp, "Axis scaling: %d\n", &gplot->scaling); 00746 00747 fclose(fp); 00748 return gplot; 00749 } 00750 00751 00752 /*! 00753 * gplotWrite() 00754 * 00755 * Input: filename 00756 * gplot 00757 * Return: 0 if OK; 1 on error 00758 */ 00759 l_int32 00760 gplotWrite(const char *filename, 00761 GPLOT *gplot) 00762 { 00763 FILE *fp; 00764 00765 PROCNAME("gplotWrite"); 00766 00767 if (!filename) 00768 return ERROR_INT("filename not defined", procName, 1); 00769 if (!gplot) 00770 return ERROR_INT("gplot not defined", procName, 1); 00771 00772 if ((fp = fopenWriteStream(filename, "wb")) == NULL) 00773 return ERROR_INT("stream not opened", procName, 1); 00774 00775 fprintf(fp, "Gplot Version %d\n", GPLOT_VERSION_NUMBER); 00776 fprintf(fp, "Rootname: %s\n", gplot->rootname); 00777 fprintf(fp, "Output format: %d\n", gplot->outformat); 00778 fprintf(fp, "Title: %s\n", gplot->title); 00779 fprintf(fp, "X axis label: %s\n", gplot->xlabel); 00780 fprintf(fp, "Y axis label: %s\n", gplot->ylabel); 00781 00782 fprintf(fp, "Commandfile name: %s\n", gplot->cmdname); 00783 fprintf(fp, "\nCommandfile data:"); 00784 sarrayWriteStream(fp, gplot->cmddata); 00785 fprintf(fp, "\nDatafile names:"); 00786 sarrayWriteStream(fp, gplot->datanames); 00787 fprintf(fp, "\nPlot data:"); 00788 sarrayWriteStream(fp, gplot->plotdata); 00789 fprintf(fp, "\nPlot titles:"); 00790 sarrayWriteStream(fp, gplot->plottitles); 00791 fprintf(fp, "\nPlot styles:"); 00792 numaWriteStream(fp, gplot->plotstyles); 00793 00794 fprintf(fp, "Number of plots: %d\n", gplot->nplots); 00795 fprintf(fp, "Output file name: %s\n", gplot->outname); 00796 fprintf(fp, "Axis scaling: %d\n", gplot->scaling); 00797 00798 fclose(fp); 00799 return 0; 00800 } 00801 00802