gnuplot_i.c

Go to the documentation of this file.
00001 
00002 
00003 /*-------------------------------------------------------------------------*/
00017 /*--------------------------------------------------------------------------*/
00018 
00019 /*
00020     $Id: gnuplot_i.c,v 2.10 2003/01/27 08:58:04 ndevilla Exp $
00021     $Author: ndevilla $
00022     $Date: 2003/01/27 08:58:04 $
00023     $Revision: 2.10 $
00024  */
00025 
00026 /*---------------------------------------------------------------------------
00027                                 Includes
00028  ---------------------------------------------------------------------------*/
00029 
00030 #include "gnuplot_i.h"
00031 
00032 /*---------------------------------------------------------------------------
00033                                 Defines
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                             Function codes
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     /* Trivial case: try in CWD */
00091     sprintf(buf, "./%s", pname) ;
00092     if (access(buf, X_OK)==0) {
00093         sprintf(buf, ".");
00094         return buf ;
00095     }
00096     /* Try out in all paths given in the PATH variable */
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                 /* Found it! */
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     /* If the buffer is still empty, the command was not found */
00119     if (buf[0] == 0) return NULL ;
00120     /* Otherwise truncate the command name to yield path only */
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      * Structure initialization:
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     /* Open one more temporary file? */
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     /* Open temporary file for output   */
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     /* Store file name in array for future deletion */
00421     strcpy(handle->to_delete[handle->ntmp], name) ;
00422     handle->ntmp ++ ;
00423     /* Write data to this file  */
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     /* Command to be sent to gnuplot    */
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     /* send command to gnuplot  */
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     /* Open one more temporary file? */
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     /* Open temporary file for output   */
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     /* Store file name in array for future deletion */
00515     strcpy(handle->to_delete[handle->ntmp], name) ;
00516     handle->ntmp ++ ;
00517 
00518     /* Write data to this file  */
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     /* Command to be sent to gnuplot    */
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     /* send command to gnuplot  */
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 /* vim: set ts=4 et sw=4 tw=75 */

Last modified: Mon Jan 27 10:00:38 2003