00001
00002
00003
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include "gnuplot_i.h"
00031
00032
00033
00034
00035
00037 #define GP_CMD_SIZE 2048
00038
00039 #define GP_TITLE_SIZE 80
00040
00041 #define GP_EQ_SIZE 512
00042
00043 #define PATH_MAXNAMESZ 4096
00044
00046 #ifndef P_tmpdir
00047 #define P_tmpdir "."
00048 #endif
00049
00050
00051
00052
00053
00054
00055
00083
00084 char * gnuplot_get_program_path(char * pname)
00085 {
00086 int i, j, lg;
00087 char * path;
00088 static char buf[PATH_MAXNAMESZ];
00089
00090
00091 sprintf(buf, "./%s", pname) ;
00092 if (access(buf, X_OK)==0) {
00093 sprintf(buf, ".");
00094 return buf ;
00095 }
00096
00097 buf[0] = 0;
00098 path = getenv("PATH") ;
00099 if (path!=NULL) {
00100 for (i=0; path[i]; ) {
00101 for (j=i ; (path[j]) && (path[j]!=':') ; j++);
00102 lg = j - i;
00103 strncpy(buf, path + i, lg);
00104 if (lg == 0) buf[lg++] = '.';
00105 buf[lg++] = '/';
00106 strcpy(buf + lg, pname);
00107 if (access(buf, X_OK) == 0) {
00108
00109 break ;
00110 }
00111 buf[0] = 0;
00112 i = j;
00113 if (path[i] == ':') i++ ;
00114 }
00115 } else {
00116 fprintf(stderr, "PATH variable not set\n");
00117 }
00118
00119 if (buf[0] == 0) return NULL ;
00120
00121 lg = strlen(buf) - 1 ;
00122 while (buf[lg]!='/') {
00123 buf[lg]=0 ;
00124 lg -- ;
00125 }
00126 buf[lg] = 0;
00127 return buf ;
00128 }
00129
00130
00131
00132
00143
00144
00145 gnuplot_ctrl * gnuplot_init(void)
00146 {
00147 gnuplot_ctrl * handle ;
00148
00149 if (getenv("DISPLAY") == NULL) {
00150 fprintf(stderr, "cannot find DISPLAY variable: is it set?\n") ;
00151 }
00152 if (gnuplot_get_program_path("gnuplot")==NULL) {
00153 fprintf(stderr, "cannot find gnuplot in your PATH");
00154 return NULL ;
00155 }
00156
00157
00158
00159
00160 handle = (gnuplot_ctrl*)malloc(sizeof(gnuplot_ctrl)) ;
00161 handle->nplots = 0 ;
00162 gnuplot_setstyle(handle, "points") ;
00163 handle->ntmp = 0 ;
00164
00165 handle->gnucmd = popen("gnuplot", "w") ;
00166 if (handle->gnucmd == NULL) {
00167 fprintf(stderr, "error starting gnuplot\n") ;
00168 free(handle) ;
00169 return NULL ;
00170 }
00171 return handle;
00172 }
00173
00174
00175
00186
00187
00188 void gnuplot_close(gnuplot_ctrl * handle)
00189 {
00190 int i ;
00191
00192 if (pclose(handle->gnucmd) == -1) {
00193 fprintf(stderr, "problem closing communication to gnuplot\n") ;
00194 return ;
00195 }
00196 if (handle->ntmp) {
00197 for (i=0 ; i<handle->ntmp ; i++) {
00198 remove(handle->to_delete[i]) ;
00199 }
00200 }
00201 free(handle) ;
00202 return ;
00203 }
00204
00205
00206
00229
00230
00231 void gnuplot_cmd(gnuplot_ctrl * handle, char * cmd, ...)
00232 {
00233 va_list ap ;
00234 char local_cmd[GP_CMD_SIZE];
00235
00236 va_start(ap, cmd);
00237 vsprintf(local_cmd, cmd, ap);
00238 va_end(ap);
00239
00240 strcat(local_cmd, "\n");
00241
00242 fputs(local_cmd, handle->gnucmd) ;
00243 fflush(handle->gnucmd) ;
00244 return ;
00245 }
00246
00247
00248
00268
00269
00270 void gnuplot_setstyle(gnuplot_ctrl * h, char * plot_style)
00271 {
00272 if (strcmp(plot_style, "lines") &&
00273 strcmp(plot_style, "points") &&
00274 strcmp(plot_style, "linespoints") &&
00275 strcmp(plot_style, "impulses") &&
00276 strcmp(plot_style, "dots") &&
00277 strcmp(plot_style, "steps") &&
00278 strcmp(plot_style, "errorbars") &&
00279 strcmp(plot_style, "boxes") &&
00280 strcmp(plot_style, "boxerrorbars")) {
00281 fprintf(stderr, "warning: unknown requested style: using points\n") ;
00282 strcpy(h->pstyle, "points") ;
00283 } else {
00284 strcpy(h->pstyle, plot_style) ;
00285 }
00286 return ;
00287 }
00288
00289
00290
00299
00300
00301 void gnuplot_set_xlabel(gnuplot_ctrl * h, char * label)
00302 {
00303 char cmd[GP_CMD_SIZE] ;
00304
00305 sprintf(cmd, "set xlabel \"%s\"", label) ;
00306 gnuplot_cmd(h, cmd) ;
00307 return ;
00308 }
00309
00310
00311
00320
00321
00322 void gnuplot_set_ylabel(gnuplot_ctrl * h, char * label)
00323 {
00324 char cmd[GP_CMD_SIZE] ;
00325
00326 sprintf(cmd, "set ylabel \"%s\"", label) ;
00327 gnuplot_cmd(h, cmd) ;
00328 return ;
00329 }
00330
00331
00332
00341
00342
00343 void gnuplot_resetplot(gnuplot_ctrl * h)
00344 {
00345 int i ;
00346 if (h->ntmp) {
00347 for (i=0 ; i<h->ntmp ; i++) {
00348 remove(h->to_delete[i]) ;
00349 }
00350 }
00351 h->ntmp = 0 ;
00352 h->nplots = 0 ;
00353 return ;
00354 }
00355
00356
00357
00358
00387
00388
00389 void gnuplot_plot_x(
00390 gnuplot_ctrl * handle,
00391 double * d,
00392 int n,
00393 char * title
00394 )
00395 {
00396 int i ;
00397 int tmpfd ;
00398 char name[128] ;
00399 char cmd[GP_CMD_SIZE] ;
00400 char line[GP_CMD_SIZE] ;
00401
00402
00403 if (handle==NULL || d==NULL || (n<1)) return ;
00404
00405
00406 if (handle->ntmp == GP_MAX_TMP_FILES - 1) {
00407 fprintf(stderr,
00408 "maximum # of temporary files reached (%d): cannot open more",
00409 GP_MAX_TMP_FILES) ;
00410 return ;
00411 }
00412
00413
00414 sprintf(name, "%s/gnuplot-i-XXXXXX", P_tmpdir);
00415 if ((tmpfd=mkstemp(name))==-1) {
00416 fprintf(stderr,"cannot create temporary file: exiting plot") ;
00417 return ;
00418 }
00419
00420
00421 strcpy(handle->to_delete[handle->ntmp], name) ;
00422 handle->ntmp ++ ;
00423
00424 for (i=0 ; i<n ; i++) {
00425 sprintf(line, "%g\n", d[i]);
00426 write(tmpfd, line, strlen(line));
00427 }
00428 close(tmpfd) ;
00429
00430
00431 if (handle->nplots > 0) {
00432 strcpy(cmd, "replot") ;
00433 } else {
00434 strcpy(cmd, "plot") ;
00435 }
00436
00437 if (title == NULL) {
00438 sprintf(line, "%s \"%s\" with %s", cmd, name, handle->pstyle) ;
00439 } else {
00440 sprintf(line, "%s \"%s\" title \"%s\" with %s", cmd, name,
00441 title, handle->pstyle) ;
00442 }
00443
00444
00445 gnuplot_cmd(handle, line) ;
00446 handle->nplots++ ;
00447 return ;
00448 }
00449
00450
00451
00452
00482
00483
00484 void gnuplot_plot_xy(
00485 gnuplot_ctrl * handle,
00486 double * x,
00487 double * y,
00488 int n,
00489 char * title
00490 )
00491 {
00492 int i ;
00493 int tmpfd ;
00494 char name[128] ;
00495 char cmd[GP_CMD_SIZE] ;
00496 char line[GP_CMD_SIZE] ;
00497
00498 if (handle==NULL || x==NULL || y==NULL || (n<1)) return ;
00499
00500
00501 if (handle->ntmp == GP_MAX_TMP_FILES - 1) {
00502 fprintf(stderr,
00503 "maximum # of temporary files reached (%d): cannot open more",
00504 GP_MAX_TMP_FILES) ;
00505 return ;
00506 }
00507
00508
00509 sprintf(name, "%s/gnuplot-i-XXXXXX", P_tmpdir);
00510 if ((tmpfd=mkstemp(name))==-1) {
00511 fprintf(stderr,"cannot create temporary file: exiting plot") ;
00512 return ;
00513 }
00514
00515 strcpy(handle->to_delete[handle->ntmp], name) ;
00516 handle->ntmp ++ ;
00517
00518
00519 for (i=0 ; i<n; i++) {
00520 sprintf(line, "%g %g\n", x[i], y[i]) ;
00521 write(tmpfd, line, strlen(line));
00522 }
00523 close(tmpfd) ;
00524
00525
00526 if (handle->nplots > 0) {
00527 strcpy(cmd, "replot") ;
00528 } else {
00529 strcpy(cmd, "plot") ;
00530 }
00531
00532 if (title == NULL) {
00533 sprintf(line, "%s \"%s\" with %s", cmd, name, handle->pstyle) ;
00534 } else {
00535 sprintf(line, "%s \"%s\" title \"%s\" with %s", cmd, name,
00536 title, handle->pstyle) ;
00537 }
00538
00539
00540 gnuplot_cmd(handle, line) ;
00541 handle->nplots++ ;
00542 return ;
00543 }
00544
00545
00546
00547
00566
00567
00568 void gnuplot_plot_once(
00569 char * title,
00570 char * style,
00571 char * label_x,
00572 char * label_y,
00573 double * x,
00574 double * y,
00575 int n
00576 )
00577 {
00578 gnuplot_ctrl * handle ;
00579
00580 if (x==NULL || n<1) return ;
00581
00582 if ((handle = gnuplot_init()) == NULL) return ;
00583 if (style!=NULL) {
00584 gnuplot_setstyle(handle, style);
00585 } else {
00586 gnuplot_setstyle(handle, "lines");
00587 }
00588 if (label_x!=NULL) {
00589 gnuplot_set_xlabel(handle, label_x);
00590 } else {
00591 gnuplot_set_xlabel(handle, "X");
00592 }
00593 if (label_y!=NULL) {
00594 gnuplot_set_ylabel(handle, label_y);
00595 } else {
00596 gnuplot_set_ylabel(handle, "Y");
00597 }
00598 if (y==NULL) {
00599 gnuplot_plot_x(handle, x, n, title);
00600 } else {
00601 gnuplot_plot_xy(handle, x, y, n, title);
00602 }
00603 printf("press ENTER to continue\n");
00604 while (getchar()!='\n') {}
00605 gnuplot_close(handle);
00606 return ;
00607 }
00608
00609
00610
00611
00612
00636
00637
00638
00639 void gnuplot_plot_slope(
00640 gnuplot_ctrl * handle,
00641 double a,
00642 double b,
00643 char * title
00644 )
00645 {
00646 char stitle[GP_TITLE_SIZE] ;
00647 char cmd[GP_CMD_SIZE] ;
00648
00649 if (title == NULL) {
00650 strcpy(stitle, "no title") ;
00651 } else {
00652 strcpy(stitle, title) ;
00653 }
00654
00655 if (handle->nplots > 0) {
00656 sprintf(cmd, "replot %g * x + %g title \"%s\" with %s",
00657 a, b, title, handle->pstyle) ;
00658 } else {
00659 sprintf(cmd, "plot %g * x + %g title \"%s\" with %s",
00660 a, b, title, handle->pstyle) ;
00661 }
00662 gnuplot_cmd(handle, cmd) ;
00663 handle->nplots++ ;
00664 return ;
00665 }
00666
00667
00668
00691
00692
00693 void gnuplot_plot_equation(
00694 gnuplot_ctrl * h,
00695 char * equation,
00696 char * title
00697 )
00698 {
00699 char cmd[GP_CMD_SIZE];
00700 char plot_str[GP_EQ_SIZE] ;
00701 char title_str[GP_TITLE_SIZE] ;
00702
00703 if (title == NULL) {
00704 strcpy(title_str, "no title") ;
00705 } else {
00706 strcpy(title_str, title) ;
00707 }
00708 if (h->nplots > 0) {
00709 strcpy(plot_str, "replot") ;
00710 } else {
00711 strcpy(plot_str, "plot") ;
00712 }
00713
00714 sprintf(cmd, "%s %s title \"%s\" with %s",
00715 plot_str, equation, title_str, h->pstyle) ;
00716 gnuplot_cmd(h, cmd) ;
00717 h->nplots++ ;
00718 return ;
00719 }
00720
00721