4 * Copyright 2007 Zoltan Kuscsik <kuscsik@gmail.com>
6 * This file is GPLv2 as found in COPYING.
14 @version $Revision: 0.2 $
15 @brief C interface to gnuplot.
17 gnuplot is a freely available, command-driven graphical display tool for
18 Unix. It compiles and works quite well on a number of Unix flavours as
19 well as other operating systems. The following module enables sending
20 display requests to gnuplot through simple C calls.
21 This code is partially based on the gnuplot_i.h library:
22 http://ndevilla.free.fr/gnuplot/
24 --------------------------------------------------------------------------*/
32 //#include "operations.h"
36 #define GNPL_COMM_SIZE 2000
37 #define MAX_COMM_NAME_LENGTH 100
38 #define MAX_PATH_NAME_LENGTH 1000
39 #define tmp_name "/tmp/tmpdataXXXXXXX"
40 unsigned int FIRST_INIT = 1;
42 char command_list[][MAX_COMM_NAME_LENGTH] = {"gnuplot","ppmto4ym","mpeg2enc"};
44 #define NUMBER_OF_EXTERNAL_COMMANDS (sizeof command_list)/MAX_COMM_NAME_LENGTH //number of external commands
46 map<char,char> path_list;
54 void splot_data(); //plot 3d data file
55 void splot_data(char * cmd, ...);
56 void plot_data(); //plot 2d data file
57 void plot_data(char * cmd, ...);
58 void flush(); //flush gnuplot data
59 void data(char * cmd, ...); //write data to gnuplot session
60 void command(char * cmd, ...); //set gnuplot variables and draw functions
61 void mpeg_out(char * cmd, ...);
64 void fit(char * cmd, ...);
65 float get_variable(char * cmd, ...);
70 char gnuplot_fifo[(sizeof tmp_name)];
71 char gnuplot_output_fifo[(sizeof tmp_name)];
76 char * get_program_path(char * pname)
80 static char buf[MAX_PATH_NAME_LENGTH];
82 /* Trivial case: try in CWD */
83 sprintf(buf, "./%s", pname) ;
84 if (access(buf, X_OK)==0) {
88 /* Try out in all paths given in the PATH variable */
90 path = getenv("PATH") ;
92 for (i=0; path[i]; ) {
93 for (j=i ; (path[j]) && (path[j]!=':') ; j++);
95 strncpy(buf, path + i, lg);
96 if (lg == 0) buf[lg++] = '.';
98 strcpy(buf + lg, pname);
99 if (access(buf, X_OK) == 0) {
105 if (path[i] == ':') i++ ;
108 fprintf(stderr, "PATH variable not set\n");
110 /* If the buffer is still empty, the command was not found */
111 if (buf[0] == 0) return NULL ;
112 /* Otherwise truncate the command name to yield path only */
113 lg = strlen(buf) - 1 ;
114 while (buf[lg]!='/') {
124 void gnuplot_window::mpeg_out(char * cmd, ...)
127 char local_cmd[GNPL_COMM_SIZE];
130 vsprintf(local_cmd, cmd, ap);
132 strcat(local_cmd, "\n");
133 command("set term pbm color ");
134 command("set output '| ppmtoy4m -S 420mpeg2 | mpeg2enc -o %s",local_cmd);
140 void gnuplot_window::data(char * cmd, ...)
144 char local_cmd[GNPL_COMM_SIZE];
152 vsprintf(local_cmd, cmd, ap);
155 strcat(local_cmd, "\n");
156 fputs(local_cmd, input);
161 void gnuplot_window::command(char * cmd, ...)
164 char local_cmd[GNPL_COMM_SIZE];
167 vsprintf(local_cmd, cmd, ap);
170 strcat(local_cmd, "\n");
172 fprintf(pipe,local_cmd);
176 void gnuplot_window::plot_data()
178 fprintf(pipe,"plot '%s'\n",gnuplot_fifo);
180 input = fopen(gnuplot_fifo,"w");
183 void gnuplot_window::splot_data()
185 fprintf(pipe,"splot '%s'\n",gnuplot_fifo);
187 input = fopen(gnuplot_fifo,"w");
190 void gnuplot_window::splot_data(char * cmd, ...)
193 char local_cmd[GNPL_COMM_SIZE];
196 vsprintf(local_cmd, cmd, ap);
199 strcat(local_cmd, "\n");
202 fprintf(pipe,"splot '%s' %s\n",gnuplot_fifo,local_cmd);
204 input = fopen(gnuplot_fifo,"w");
206 void gnuplot_window::plot_data(char * cmd, ...)
209 char local_cmd[GNPL_COMM_SIZE];
212 vsprintf(local_cmd, cmd, ap);
215 strcat(local_cmd, "\n");
218 fprintf(pipe,"plot '%s' %s\n",gnuplot_fifo,local_cmd);
220 input = fopen(gnuplot_fifo,"w");
228 void gnuplot_window::fit(char * cmd, ...)
231 char local_cmd[GNPL_COMM_SIZE];
233 vsprintf(local_cmd, cmd, ap);
236 strcat(local_cmd, "\n");
239 fprintf(stderr,"Function for datafit is not defined. Please define the fit_function parameter\n");
241 fprintf(pipe,"fit [%s] %s '%s' %s\n",fit_range, fit_function,gnuplot_fifo,local_cmd);
243 input = fopen(gnuplot_fifo,"w");
250 void gnuplot_window::flush()
257 gnuplot_window::gnuplot_window()
260 pipe=popen("/usr/bin/gnuplot 2>/dev/null","w");
261 setvbuf(pipe, NULL, _IONBF, 0 );
263 strcpy(gnuplot_fifo,tmp_name);
264 strcpy(gnuplot_output_fifo,tmp_name);
265 if((fd=mkstemp(gnuplot_fifo) ) < 0) { fprintf(stderr,"Creating temporary filename failed\n"); exit(0);}
266 close(fd); remove(gnuplot_fifo);
268 if (mkfifo(gnuplot_fifo, S_IRUSR | S_IWUSR ) != 0) {fprintf(stderr,"Make fifo file %s failed\n",gnuplot_fifo); exit(0);}
271 if((fd=mkstemp(gnuplot_output_fifo) ) < 0) { fprintf(stderr,"Creating temporary filename failed\n"); exit(0);}
272 close(fd); remove(gnuplot_output_fifo);
274 if (mkfifo(gnuplot_output_fifo, S_IRUSR | S_IWUSR ) != 0) {fprintf(stderr,"Make fifo file %s failed\n",gnuplot_output_fifo); exit(0);}
277 command("set fit logfile '/dev/null'");
281 float gnuplot_window::get_variable(char * cmd, ...)
284 char local_cmd[GNPL_COMM_SIZE];
286 vsprintf(local_cmd, cmd, ap);
290 command("set print '%s'",gnuplot_output_fifo);
292 command("print %s",local_cmd);
294 usleep(10000); /* There must be a little sleep because of asynchronous relation to the gnuplot pipe*/
296 input_param=fopen(gnuplot_output_fifo,"r");
298 fscanf(input_param,"%f",¶m);