00001
00002
00003
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "gnuplot_i.h"
00031
00032 #include <stdio.h>
00033 #include <stdlib.h>
00034 #include <string.h>
00035 #include <stdarg.h>
00036 #include <assert.h>
00037
00038 #ifdef WIN32
00039 #include <io.h>
00040 #endif // #ifdef WIN32
00041
00042
00043
00044
00045
00046
00047
00048
00049
00059 char const * gnuplot_tmpfile(gnuplot_ctrl * handle);
00060
00070 void gnuplot_plot_atmpfile(gnuplot_ctrl * handle, char const* tmp_filename, char const* title);
00071
00072
00073
00074
00075
00076
00087
00088
00089 gnuplot_ctrl * gnuplot_init(void)
00090 {
00091 gnuplot_ctrl * handle ;
00092 int i;
00093
00094 #ifndef WIN32
00095 if (getenv("DISPLAY") == NULL) {
00096 fprintf(stderr, "cannot find DISPLAY variable: is it set?\n") ;
00097 }
00098 #endif // #ifndef WIN32
00099
00100
00101
00102
00103
00104 handle = (gnuplot_ctrl*)malloc(sizeof(gnuplot_ctrl)) ;
00105 handle->nplots = 0 ;
00106 gnuplot_setstyle(handle, "points") ;
00107 handle->ntmp = 0 ;
00108
00109 handle->gnucmd = popen("gnuplot", "w") ;
00110 if (handle->gnucmd == NULL) {
00111 fprintf(stderr, "error starting gnuplot, is gnuplot or gnuplot.exe in your path?\n") ;
00112 free(handle) ;
00113 return NULL ;
00114 }
00115
00116 for (i=0;i<GP_MAX_TMP_FILES; i++)
00117 {
00118 handle->tmp_filename_tbl[i] = NULL;
00119 }
00120 return handle;
00121 }
00122
00123
00124
00135
00136
00137 void gnuplot_close(gnuplot_ctrl * handle)
00138 {
00139 int i ;
00140
00141 if (pclose(handle->gnucmd) == -1) {
00142 fprintf(stderr, "problem closing communication to gnuplot\n") ;
00143 return ;
00144 }
00145 if (handle->ntmp) {
00146 for (i=0 ; i<handle->ntmp ; i++) {
00147 remove(handle->tmp_filename_tbl[i]) ;
00148 free(handle->tmp_filename_tbl[i]);
00149 handle->tmp_filename_tbl[i] = NULL;
00150
00151 }
00152 }
00153 free(handle) ;
00154 return ;
00155 }
00156
00157
00158
00181
00182
00183 void gnuplot_cmd(gnuplot_ctrl * handle, char const * cmd, ...)
00184 {
00185 va_list ap ;
00186
00187 va_start(ap, cmd);
00188 vfprintf(handle->gnucmd, cmd, ap);
00189 va_end(ap);
00190
00191 fputs("\n", handle->gnucmd) ;
00192 fflush(handle->gnucmd) ;
00193 return ;
00194 }
00195
00196
00197
00217
00218
00219 void gnuplot_setstyle(gnuplot_ctrl * h, char * plot_style)
00220 {
00221 if (strcmp(plot_style, "lines") &&
00222 strcmp(plot_style, "points") &&
00223 strcmp(plot_style, "linespoints") &&
00224 strcmp(plot_style, "impulses") &&
00225 strcmp(plot_style, "dots") &&
00226 strcmp(plot_style, "steps") &&
00227 strcmp(plot_style, "errorbars") &&
00228 strcmp(plot_style, "boxes") &&
00229 strcmp(plot_style, "boxerrorbars")) {
00230 fprintf(stderr, "warning: unknown requested style: using points\n") ;
00231 strcpy(h->pstyle, "points") ;
00232 } else {
00233 strcpy(h->pstyle, plot_style) ;
00234 }
00235 return ;
00236 }
00237
00238
00239
00248
00249
00250 void gnuplot_set_xlabel(gnuplot_ctrl * h, char * label)
00251 {
00252 gnuplot_cmd(h, "set xlabel \"%s\"", label) ;
00253 }
00254
00255
00256
00265
00266
00267 void gnuplot_set_ylabel(gnuplot_ctrl * h, char * label)
00268 {
00269 gnuplot_cmd(h, "set ylabel \"%s\"", label) ;
00270 }
00271
00272
00273
00282
00283
00284 void gnuplot_resetplot(gnuplot_ctrl * h)
00285 {
00286 int i ;
00287 if (h->ntmp) {
00288 for (i=0 ; i<h->ntmp ; i++) {
00289 remove(h->tmp_filename_tbl[i]) ;
00290 free(h->tmp_filename_tbl[i]);
00291 h->tmp_filename_tbl[i] = NULL;
00292
00293 }
00294 }
00295 h->ntmp = 0 ;
00296 h->nplots = 0 ;
00297 return ;
00298 }
00299
00300
00329
00330
00331 void gnuplot_plot_x(
00332 gnuplot_ctrl * handle,
00333 double * d,
00334 int n,
00335 char * title
00336 )
00337 {
00338 int i ;
00339 FILE* tmpfd ;
00340 char const * tmpfname;
00341
00342 if (handle==NULL || d==NULL || (n<1)) return ;
00343
00344
00345 tmpfname = gnuplot_tmpfile(handle);
00346 tmpfd = fopen(tmpfname, "w");
00347
00348 if (tmpfd == NULL) {
00349 fprintf(stderr,"cannot create temporary file: exiting plot") ;
00350 return ;
00351 }
00352
00353
00354 for (i=0 ; i<n ; i++) {
00355 fprintf(tmpfd, "%.18e\n", d[i]);
00356 }
00357 fclose(tmpfd) ;
00358
00359 gnuplot_plot_atmpfile(handle,tmpfname,title);
00360 return ;
00361 }
00362
00363
00364
00365
00395
00396
00397 void gnuplot_plot_xy(
00398 gnuplot_ctrl * handle,
00399 double * x,
00400 double * y,
00401 int n,
00402 char * title
00403 )
00404 {
00405 int i ;
00406 FILE* tmpfd ;
00407 char const * tmpfname;
00408
00409 if (handle==NULL || x==NULL || y==NULL || (n<1)) return ;
00410
00411
00412 tmpfname = gnuplot_tmpfile(handle);
00413 tmpfd = fopen(tmpfname, "w");
00414
00415 if (tmpfd == NULL) {
00416 fprintf(stderr,"cannot create temporary file: exiting plot") ;
00417 return ;
00418 }
00419
00420
00421 for (i=0 ; i<n; i++) {
00422 fprintf(tmpfd, "%.18e %.18e\n", x[i], y[i]) ;
00423 }
00424 fclose(tmpfd) ;
00425
00426 gnuplot_plot_atmpfile(handle,tmpfname,title);
00427 return ;
00428 }
00429
00430
00431
00432
00451
00452
00453 void gnuplot_plot_once(
00454 char * title,
00455 char * style,
00456 char * label_x,
00457 char * label_y,
00458 double * x,
00459 double * y,
00460 int n
00461 )
00462 {
00463 gnuplot_ctrl * handle ;
00464
00465 if (x==NULL || n<1) return ;
00466
00467 if ((handle = gnuplot_init()) == NULL) return ;
00468 if (style!=NULL) {
00469 gnuplot_setstyle(handle, style);
00470 } else {
00471 gnuplot_setstyle(handle, "lines");
00472 }
00473 if (label_x!=NULL) {
00474 gnuplot_set_xlabel(handle, label_x);
00475 } else {
00476 gnuplot_set_xlabel(handle, "X");
00477 }
00478 if (label_y!=NULL) {
00479 gnuplot_set_ylabel(handle, label_y);
00480 } else {
00481 gnuplot_set_ylabel(handle, "Y");
00482 }
00483 if (y==NULL) {
00484 gnuplot_plot_x(handle, x, n, title);
00485 } else {
00486 gnuplot_plot_xy(handle, x, y, n, title);
00487 }
00488 printf("press ENTER to continue\n");
00489 while (getchar()!='\n') {}
00490 gnuplot_close(handle);
00491 return ;
00492 }
00493
00494 void gnuplot_plot_slope(
00495 gnuplot_ctrl * handle,
00496 double a,
00497 double b,
00498 char * title
00499 )
00500 {
00501 char const * cmd = (handle->nplots > 0) ? "replot" : "plot";
00502 title = (title == NULL) ? "(none)" : title;
00503
00504 gnuplot_cmd(handle, "%s %.18e * x + %.18e title \"%s\" with %s",
00505 cmd, a, b, title, handle->pstyle) ;
00506
00507 handle->nplots++ ;
00508 return ;
00509 }
00510
00511
00512 void gnuplot_plot_equation(
00513 gnuplot_ctrl * h,
00514 char * equation,
00515 char * title
00516 )
00517 {
00518 char const * cmd = (h->nplots > 0) ? "replot" : "plot";
00519 title = (title == NULL) ? "(none)" : title;
00520
00521 gnuplot_cmd(h, "%s %s title \"%s\" with %s",
00522 cmd, equation, title, h->pstyle) ;
00523 h->nplots++ ;
00524 return ;
00525 }
00526
00527
00528 int gnuplot_write_x_csv(
00529 char const * fileName,
00530 double const * d,
00531 int n,
00532 char const * title)
00533 {
00534 int i;
00535 FILE* fileHandle;
00536
00537 if (fileName==NULL || d==NULL || (n<1))
00538 {
00539 return -1;
00540 }
00541
00542 fileHandle = fopen(fileName, "w");
00543
00544 if (fileHandle == NULL)
00545 {
00546 return -1;
00547 }
00548
00549
00550 if (title != NULL)
00551 {
00552 fprintf(fileHandle, "# %s\n", title) ;
00553 }
00554
00555
00556 for (i=0 ; i<n; i++)
00557 {
00558 fprintf(fileHandle, "%d, %.18e\n", i, d[i]) ;
00559 }
00560
00561 fclose(fileHandle) ;
00562
00563 return 0;
00564 }
00565
00566 int gnuplot_write_xy_csv(
00567 char const * fileName,
00568 double const * x,
00569 double const * y,
00570 int n,
00571 char const * title)
00572 {
00573 int i ;
00574 FILE* fileHandle;
00575
00576 if (fileName==NULL || x==NULL || y==NULL || (n<1))
00577 {
00578 return -1;
00579 }
00580
00581 fileHandle = fopen(fileName, "w");
00582
00583 if (fileHandle == NULL)
00584 {
00585 return -1;
00586 }
00587
00588
00589 if (title != NULL)
00590 {
00591 fprintf(fileHandle, "# %s\n", title) ;
00592 }
00593
00594
00595 for (i=0 ; i<n; i++)
00596 {
00597 fprintf(fileHandle, "%.18e, %.18e\n", x[i], y[i]) ;
00598 }
00599
00600 fclose(fileHandle) ;
00601
00602 return 0;
00603 }
00604
00605 int gnuplot_write_multi_csv(
00606 char const * fileName,
00607 double const ** xListPtr,
00608 int n,
00609 int numColumns,
00610 char const * title)
00611 {
00612 int i;
00613 int j;
00614 FILE* fileHandle;
00615
00616 if (fileName==NULL || xListPtr==NULL || (n<1) || numColumns <1)
00617 {
00618 return -1;
00619 }
00620
00621 for (j=0;j<numColumns;j++)
00622 {
00623 if (xListPtr[j] == NULL)
00624 {
00625 return -1;
00626 }
00627 }
00628
00629 fileHandle = fopen(fileName, "w");
00630
00631 if (fileHandle == NULL)
00632 {
00633 return -1;
00634 }
00635
00636
00637 if (title != NULL)
00638 {
00639 fprintf(fileHandle, "# %s\n", title) ;
00640 }
00641
00642
00643 for (i=0 ; i<n; i++)
00644 {
00645 fprintf(fileHandle, "%d, %.18e", i, xListPtr[0][i]) ;
00646 for (j=1;j<numColumns;j++)
00647 {
00648 fprintf(fileHandle, ", %.18e", xListPtr[j][i]) ;
00649 }
00650 fprintf(fileHandle, "\n");
00651 }
00652
00653 fclose(fileHandle) ;
00654
00655 return 0;
00656 }
00657
00658 char const * gnuplot_tmpfile(gnuplot_ctrl * handle)
00659 {
00660 static char const * tmp_filename_template = "gnuplot_tmpdatafile_XXXXXX";
00661 char * tmp_filename = NULL;
00662 int tmp_filelen = strlen(tmp_filename_template);
00663
00664 #ifndef WIN32
00665 int unx_fd;
00666 #endif // #ifndef WIN32
00667
00668 assert(handle->tmp_filename_tbl[handle->ntmp] == NULL);
00669
00670
00671 if (handle->ntmp == GP_MAX_TMP_FILES - 1) {
00672 fprintf(stderr,
00673 "maximum # of temporary files reached (%d): cannot open more",
00674 GP_MAX_TMP_FILES) ;
00675 return NULL;
00676 }
00677
00678 tmp_filename = (char*) malloc(tmp_filelen+1);
00679 if (tmp_filename == NULL)
00680 {
00681 return NULL;
00682 }
00683 strcpy(tmp_filename, tmp_filename_template);
00684
00685 #ifdef WIN32
00686 if (_mktemp(tmp_filename) == NULL)
00687 {
00688 return NULL;
00689 }
00690 #else // #ifdef WIN32
00691 unx_fd = mkstemp(tmp_filename);
00692 if (unx_fd == -1)
00693 {
00694 return NULL;
00695 }
00696 close(unx_fd);
00697
00698 #endif // #ifdef WIN32
00699
00700 handle->tmp_filename_tbl[handle->ntmp] = tmp_filename;
00701 handle->ntmp ++;
00702 return tmp_filename;
00703 }
00704
00705 void gnuplot_plot_atmpfile(gnuplot_ctrl * handle, char const* tmp_filename, char const* title)
00706 {
00707 char const * cmd = (handle->nplots > 0) ? "replot" : "plot";
00708 title = (title == NULL) ? "(none)" : title;
00709 gnuplot_cmd(handle, "%s \"%s\" title \"%s\" with %s", cmd, tmp_filename,
00710 title, handle->pstyle) ;
00711 handle->nplots++ ;
00712 return ;
00713 }
00714
00715
00716