ROBOOP, A Robotics Object Oriented Package in C++
gnugraph.cpp
Go to the documentation of this file.
1 /*
2 ROBOOP -- A robotics object oriented package in C++
3 Copyright (C) 1996-2004 Richard Gourdeau
4 
5 This library is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as
7 published by the Free Software Foundation; either version 2.1 of the
8 License, or (at your option) any later version.
9 
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
14 
15 You should have received a copy of the GNU Lesser General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18 
19 
20 Report problems and direct all questions to:
21 
22 Richard Gourdeau, Professeur
23 Departement de genie electrique
24 Ecole Polytechnique de Montreal
25 C.P. 6079, Succ. Centre-Ville
26 Montreal, Quebec, H3C 3A7
27 
28 email: richard.gourdeau@polymtl.ca
29 
30 -------------------------------------------------------------------------------
31 Revision_history:
32 
33 2003/02/03: Etienne Lachance
34  -Added functions set_plot2d and classe IO_matrix_file.
35 
36 2003/29/04: Etienne Lachance
37  -Class definitions, functions prototype, ... now in gnugraph.h
38  -Improved class IO_matrix_file.
39  -Class Plot2d, GNUcurve are now using STL string instead of char*.
40  -Added class Plot_graph, to create a graph from a data file.
41  -Replaced all NULL by 0.
42  -Use mkstemp instead of tmpnam in void Plot2d::gnuplot(void).
43 
44 2003/15/08: Etienne Lachance
45  -The member function IO_matrix_file::write writes data in column of each
46  variables, instead of only one. This way it is possible to load a dat file
47  in Matlab.
48 
49 2004/07/01: Etienne Lachance
50  -Added doxygen documentation.
51 
52 2004/07/01: Ethan Tira-Thompson
53  -Added support for newmat's use_namespace #define, using ROBOOP namespace
54 
55 2004/08/10: Etienne Lachance
56  -Added class Plot3d.
57  -Removed using ROBOOP namespace
58 
59 2005/08/06 : Richard Gourdeau
60  -fixed catch(bad_alloc)
61 
62 2005/08/06 : Carmine Lia
63  -added defined(__MINGW32__) for temp files
64 -------------------------------------------------------------------------------
65 */
66 
72 #include "gnugraph.h"
73 
74 using namespace std;
75 
76 
77 const char *curvetype[] =
78  {"lines",
79  "points",
80  "linespoints",
81  "impulses",
82  "dots",
83  "steps",
84  "boxes"};
85 
86 
89 {
90  enLineType = LINES;
91 }
92 
93 
94 GNUcurve::GNUcurve(const std::vector<double> & x, std::vector<double> & y,
95  const string & label, LineType_en enLineType_) :
96  vdX(x),
97  vdY(y),
98  clabel(label),
99  enLineType(enLineType_)
101 {
102  if (vdX.size() != vdY.size())
103  {
104  cerr << "GNUcurve::GNUcurve number of x and y elements does not match." << endl;
105  }
106 }
107 
108 void GNUcurve::dump(void)
110 {
111  cout << "Curve label: " << clabel << endl;
112  cout << "Curve type: " << curvetype[enLineType] << endl;
113  cout << "Curve data points: \n";
114 
115  unsigned int vSize = vdX.size();
116  for(unsigned int i = 0; i < vSize; ++i)
117  {
118  cout << vdX[i] << " " << vdY[i] << endl;
119  }
120  cout << endl;
121 }
122 
123 
126 {
127 }
128 
129 void Plot2d::gnuplot(void)
131 {
132  unsigned int i;
133  int strl;
134 #if defined(__BCPLUSPLUS__) || defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__)
135  char filename[L_tmpnam];
136 #else
137  char filename[] = "tmpfileXXXXXX";
138 #endif
139  char * filedata=0;
140  char * wibsl;
141  char bsl = '\\';
142 
143 #if defined(__BCPLUSPLUS__) || defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__)
144  tmpnam(filename); /* generate a temporary file name */
145 #else
146  mkstemp(filename);
147 #endif
148  /* replacing \ by / */
149  while((wibsl = strchr(filename,bsl)) != 0) {
150  wibsl[0] = '/';
151  }
152 
153  {
154  ofstream fileout(filename); /* write the command file */
155  fileout << gnucommand.c_str();
156  fileout << "set title \"" << title << "\"\n";
157  fileout << "set xlabel \"" << xlabel << "\"\n";
158  fileout << "set ylabel \"" << ylabel << "\"\n";
159  fileout << "plot \\\n";
160 
161  for(i = 0; i < vCurves.size(); i++) {
162  fileout << "\"" << filename << "." << i << "\" ";
163  fileout << "title \"" << vCurves[i]->clabel << "\" ";
164  fileout << "with " << curvetype[vCurves[i]->enLineType] << " ";
165  if( i+1 < vCurves.size()){
166  fileout << ", \\\n";
167  }
168  }
169  fileout << "\n";
170  }
171  try
172  {
173  filedata = new char[strlen(filename)+3];
174  }
175  catch(bad_alloc & e)
176  {
177  cerr << "Plot2d::gnuplot:: new ran out of memory" << endl;
178  }
179  strcpy(filedata,filename);
180  strcat(filedata,".");
181  strl = strlen(filedata);
182 
183  for(i = 0; i < vCurves.size(); i++) /* write the data files */
184  {
185  sprintf(&filedata[strl],"%d",i);
186  ofstream fileout(filedata);
187 
188 //#ifndef _MSC_VER // MSVC++ chokes on the next line !
189  // fileout << curves[i].xy;
190 //#else
191  unsigned int vSize = vCurves[i]->vdX.size();
192  for (unsigned int j = 0; j < vSize; ++j)
193  {
194  fileout << vCurves[i]->vdX[j] << " " << vCurves[i]->vdY[j] << endl;
195  }
196 
197 /*
198  for(int j = 1; j <= curves[i].xy.Nrows(); j++) {
199  for(int k = 1; k <= curves[i].xy.Ncols(); k++) {
200  fileout << curves[i].xy(j,k) << " ";
201  }
202  fileout << "\n";
203  }
204 */
205 //#endif
206  }
207  /* all command and data files are ready for the call to gnuplot */
208  FILE *command;
209 
210  command = popen(GNUPLOT,"w");
211  fprintf(command,"load \"%s\"\n",filename); fflush(command);
212  fprintf(stderr,"Press Enter to continue...\n"); fflush(stderr);
213  getchar();
214  pclose(command);
215 
216  remove(filename);
217  for(i = 0; i < vCurves.size(); i++) {
218  sprintf(&filedata[strl],"%d",i);
219  remove(filedata);
220  }
221  delete filedata;
222 }
223 
224 
225 void Plot2d::addcurve(const Matrix & data, const string & label, LineType_en enLineType)
227 {
228  vector<double> x;
229  vector<double> y;
230 
231  for(int j = 1; j <= data.Nrows(); j++)
232  {
233  x.push_back(data(j,1));
234  y.push_back(data(j,2));
235  }
236 
237  try
238  {
239  GNUcurve *pCurve = new GNUcurve(x, y, label, enLineType);
240  vCurves.push_back(PSHR_Curve(pCurve));
241  }
242  catch (bad_alloc & e)
243  {
244  }
245 }
246 
247 void Plot2d::addcommand(const string & gcom)
249 {
250  gnucommand += gcom;
251 }
252 
253 void Plot2d::settitle(const string & t)
255 {
256  title = t;
257 }
258 
259 void Plot2d::setxlabel(const string & t)
261 {
262  xlabel = t;
263 }
264 
265 void Plot2d::setylabel(const string & t)
267 {
268  ylabel = t;
269 }
270 
271 void Plot2d::dump(void)
273 {
274  cout << "gnuplot commands:\n" << gnucommand.c_str();
275  cout << "Plot title: " << title.c_str() << "\n";
276  cout << "X label: " << xlabel.c_str() << "\n";
277  cout << "Y label: " << ylabel.c_str() << "\n";
278 
279  for (unsigned int i = 0; i < vCurves.size(); ++i)
280  {
281  cout << "\nCurve #" << i << "\n";
282  vCurves[i]->dump();
283  }
284 }
285 
286 
287 void Plot3d::gnuplot(const Matrix & xyz)
289 {
290  if (xyz.Ncols() != 3*xyz.Nrows())
291  {
292  cerr << "Plot3d::gnuplot: wrong size of xyz data matrix." << endl;
293  return;
294  }
295 
296  int strl;
297 #if defined(__BCPLUSPLUS__) || defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__)
298  char filename[L_tmpnam];
299 #else
300  char filename[] = "tmpfileXXXXXX";
301 #endif
302  char * filedata=0;
303  char * wibsl;
304  char bsl = '\\';
305 
306 #if defined(__BCPLUSPLUS__) || defined(_MSC_VER) || defined(__WATCOMC__) || defined(__MINGW32__)
307  tmpnam(filename); /* generate a temporary file name */
308 #else
309  mkstemp(filename);
310 #endif
311 
312  while((wibsl = strchr(filename,bsl)) != 0) {
313  wibsl[0] = '/';
314  }
315  {
316  ofstream fileout(filename); // write the command file
317  fileout << "set title \"" << title << "\"\n";
318  fileout << "set xlabel \"" << xlabel << "\"\n";
319  fileout << "set ylabel \"" << ylabel << "\"\n";
320  fileout << "set zlabel \"" << zlabel << "\"\n";
321  fileout << "splot \\\n";
322  fileout << "\"" << filename << "." << 0 << "\" ";
323  fileout << "title \"" << "" << "\" ";
324  fileout << "with " << "linespoints" << " ";
325  }
326 
327  try
328  {
329  filedata = new char[strlen(filename)+3];
330  }
331  catch(bad_alloc & e)
332  {
333  cerr << "Plot3d::gnuplot:: new ran out of memory" << endl;
334  }
335  strcpy(filedata,filename);
336  strcat(filedata,".");
337  strl = strlen(filedata);
338 
339  sprintf(&filedata[strl],"%d",0);
340  ofstream fileout(filedata);
341 
342  for(int j = 0; j < 3*xyz.Nrows(); j+=3)
343  {
344  fileout << xyz.SubMatrix(1, xyz.Nrows(), j+1, j+3);
345  fileout << " " << endl;
346  }
347 
348 #if defined(__WIN32__) || defined(_WIN32) || defined(__NT__) || defined(__CYGWIN__) || defined(__MINGW32__)
349  /* Windows 95/98/NT/2000 etc */
350  char c[L_tmpnam+15];
351  char *d;
352  HWND hwndm, hwnd;
353  if (WinExec(GNUPLOT, SW_SHOWNORMAL) <= 32) { /* start gnuplot */
354  /* failed */
355  cout << "Cannot find the gnuplot application\n";
356  cout << "Press Enter to continue" << endl;
357  getchar();
358  remove(filename); /* clean up the files and return */
359  remove(filedata);
360  delete filedata;
361  return;
362  } else { /* succeed */
363  /* get gnuplot main window handle */
364  hwndm = FindWindow((LPSTR) 0, (LPSTR) "gnuplot");
365  }
366  hwnd= GetWindow(hwndm, GW_CHILD); /* get gnuplot command area handle */
367  if(hwnd == 0) cout << "OUPS!!!\n"; /* something wrong happened */
368  sprintf(c,"load \"%s\" \n",filename); /* load command for the plot */
369 
370 #ifdef __GNUG__ /* Cygnus Gnu C++ for win32*/
371  char ccygnus[] = "cd \"c:\"\n"; /* this string should reflect
372  the drive used to mount /
373  where /tmp is located */
374  d = ccygnus;
375  while(*d != '\0') { /* sending the command through windows messages */
376  SendMessage(hwnd,WM_CHAR,*d,1L);
377  d++;
378  }
379 #endif
380  d = c;
381  while(*d != '\0') { /* sending the command through windows messages */
382  SendMessage(hwnd,WM_CHAR,*d,1L);
383  d++;
384  }
385  cout << "Press Enter to continue..." << endl;
386  getchar();
387 #else /* using a pipe under Unix */
388  FILE *command;
389  command = popen(GNUPLOT,"w");
390  fprintf(command,"load \"%s\"\n",filename); fflush(command);
391  fprintf(stderr,"Press Enter to continue...\n"); fflush(stderr);
392  getchar();
393  pclose(command);
394 #endif
395 
396  remove(filename);
397  sprintf(&filedata[strl],"%d",0);
398  remove(filedata);
399 
400  delete filedata;
401 }
402 
403 void Plot3d::settitle(const string & t)
405 {
406  title = t;
407 }
408 
409 void Plot3d::setxlabel(const string & t)
411 {
412  xlabel = t;
413 }
414 
415 void Plot3d::setylabel(const string & t)
417 {
418  ylabel = t;
419 }
420 
421 void Plot3d::setzlabel(const string & t)
423 {
424  zlabel = t;
425 }
426 
427 // ---------------------------------------------------------------------------------------
428 
429 IO_matrix_file::IO_matrix_file(const string & filename_)
431 {
432  filename = filename_;
433  position_read = 0;
435  nb_iterations_read = 0;
436  nb_element = 0;
437 }
438 
439 
440 short IO_matrix_file::write(const vector<Matrix> & data)
442 {
443  vector<string> title;
444  string tmp;
445  for(unsigned int i = 1; i <= data.size(); i++)
446  {
447  tmp = "data#"; // Provide a default name
448  tmp += i;
449  title.push_back(tmp);
450  }
451 
452  return IO_matrix_file::write(data, title);
453 }
454 
455 
456 short IO_matrix_file::write(const vector<Matrix> & data, const vector<string> & title)
462 {
463  /*
464  If the file "filename" does not exist yet, created it. The first lines of the file
465  contain the following informations (for each line):
466  1) the number of iterations.
467  2) second line is empty.
468  3) the number(n) of matrix/iteration
469  4) number of rows and number of columns of Matrix 1.
470  5) " " i.
471  6) " " n.
472  7)--------------------------------- (end of header file)
473 
474  example of header file;
475  1120
476 
477  2
478  6 1 titre#1
479  6 1 titre#1
480  ---------------------------------
481  */
482  const char *ptr_filename = filename.c_str(); // transform string to *char
483  if(data.size())
484  {
486  {
487  struct stat buf;
488  if(stat(ptr_filename, &buf) ) // File does not exist
489  {
490  ofstream outvecfile(ptr_filename);
491  if(outvecfile)
492  {
493  outvecfile << "nd_iterations " << nb_iterations_write
494  << " " << endl;
495  outvecfile << "nb_vector " << data.size() << endl;
496  for(unsigned int i = 0; i < data.size(); i++)
497  outvecfile << "nb_rows " << data[i].Nrows() << " "
498  << "nb_cols " << data[i].Ncols() << " "
499  << title[i] << endl;
500  outvecfile << "---------------------------------\n";
501  }
502  else
503  {
504  cerr << "IO_matrix_file::write: can not open file " << filename.c_str() << endl;
505  return IO_COULD_NOT_OPEN_FILE;
506  }
507  }
508  else
509  {
510  ifstream invecfile(ptr_filename, ios::in);
511  if(invecfile)
512  invecfile >> nb_iterations_write;
513  }
514  }
515 
516  ofstream outvecfile(ptr_filename, ios::in | ios::out);
517  if(outvecfile)
518  {
519  outvecfile.seekp(strlen("nb_iterations ")); // position at start of fileObject
520  outvecfile << ++nb_iterations_write << endl;
521  outvecfile.seekp(0, std::ios::end); // position at end of fileObject
522  for(unsigned int i = 0; i < data.size(); i++)
523  {
524  for(int j = 1; j <= data[i].Nrows(); j++) {
525  for(int k = 1; k <= data[i].Ncols(); k++) {
526  outvecfile << data[i](j,k) << " ";
527  }
528  }
529  }
530  outvecfile << endl;
531  outvecfile << endl;
532  }
533  else
534  {
535  cerr << "IO_matrix_file::write: can not open file " << filename.c_str() << endl;
536  return IO_COULD_NOT_OPEN_FILE;
537  }
538  }
539  else
540  {
541  cerr << "IO_matrix_file::write: vector data is empty" << endl;
542  return IO_DATA_EMPTY;
543  }
544 
545  return 0;
546 }
547 
548 
549 short IO_matrix_file::read(vector<Matrix> & data)
551 {
552  vector<string> data_title;
553  string tmp;
554  for(unsigned int i = 1; i <= data.size(); i++)
555  {
556  tmp = "data#"; // Provide a default name
557  tmp += i;
558  data_title.push_back(tmp);
559  }
560 
561  return IO_matrix_file::read(data, data_title);
562 }
563 
564 
565 short IO_matrix_file::read(vector<Matrix> & data, vector<string> & data_title)
567 {
568  /*
569  If the file "filename does not exist yet, created it and fill the first line
570  with the number of rows and columns for each element of "data".
571  ex: 6x1;3x1;3x3;
572  This line indidate that data has 3 elements Matrix. The first one has 6 rows and
573  1 columns, the second one has 3 rows and 1 columns ...
574  */
575  static const char *ptr_filename = filename.c_str(); // transform string to *char
576  ifstream invecfile(ptr_filename, ios::in);
577 
578  if(invecfile)
579  {
580  if(!position_read)
581  {
582  string temp;
583  int nbcol = 0, nbrow = 0;
584  invecfile >> temp >> nb_iterations_read;
585  invecfile >> temp >> nb_element;
586  Matrix mat_tmp;
587  data.clear();
588  data_title.clear();
589  for(int i = 1; i <= nb_element; i++)
590  {
591  data.push_back(mat_tmp);
592  data_title.push_back(temp);
593  }
594  for(int j = 0; j < nb_element; j++)
595  {
596  invecfile >> temp >> nbrow;
597  invecfile >> temp >> nbcol;
598  getline(invecfile,data_title[j]);
599  if( (nbrow != data[j].Nrows()) ||
600  (nbcol != data[j].Ncols()) )
601  data[j] = Matrix(nbrow, nbcol);
602  }
603  invecfile >> temp; //------------------------
604  position_read = invecfile.tellg();
605  }
606 
607  if(position_read > 0)
608  {
609  invecfile.seekg(position_read); // position for reading
610  for(unsigned int ii = 0; ii < data.size(); ii++)
611  for(int jj = 1; jj <= data[ii].Nrows(); jj++)
612  for(int kk = 1; kk <= data[ii].Ncols(); kk++)
613  invecfile >> data[ii](jj,kk);
614 
615  position_read = invecfile.tellg(); // position for next reading
616  }
617  }
618  else
619  {
620  cerr << "IO_matrix_file::read, can not open file" << filename.c_str() << endl;
621  return IO_COULD_NOT_OPEN_FILE;
622  }
623  return 0;
624 }
625 
626 
627 short IO_matrix_file::read_all(vector<Matrix> & data, vector<string> & data_title)
637 {
638  static const char *ptr_filename = filename.c_str(); // transform string to *char
639  ifstream invecfile(ptr_filename, ios::in);
640 
641  if(invecfile)
642  {
643  string temp;
644  int nbcol = 0, nbrow = 0;
645  invecfile >> temp >> nb_iterations_read;
646  invecfile >> temp >> nb_element;
647 
648  Matrix mat_tmp;
649  data.clear();
650  data_title.clear();
651  for(int i = 1; i <= nb_element; i++)
652  {
653  data.push_back(mat_tmp);
654  data_title.push_back(" ");
655  }
656 
657  for(int j = 0; j < nb_element; j++)
658  {
659  invecfile >> temp >> nbrow;
660  invecfile >> temp >> nbcol;
661  if(nbcol >1)
662  return IO_MISMATCH_SIZE;
663 
664  getline(invecfile,data_title[j]);
665  if( (nbrow != data[j].Nrows()) ||
666  (nbcol != data[j].Ncols()) )
667  data[j] = Matrix(nbrow, nbcol*nb_iterations_read);
668  }
669  invecfile >> temp; //---------------------------------
670 
671  for(int k = 1; k <= nb_iterations_read; k++)
672  for(unsigned int ii = 0; ii < data.size(); ii++)
673  for(int jj = 1; jj <= data[ii].Nrows(); jj++)
674  invecfile >> data[ii](jj,k);
675  }
676  else
677  {
678  cerr << "IO_matrix_file::read_all, can not open file " << filename.c_str() << endl;
679  return IO_COULD_NOT_OPEN_FILE;
680  }
681  return 0;
682 }
683 
684 // ---------------------------------------------------------------------------------------
685 
692 Plot_file::Plot_file(const string & filename) : IO_matrix_file(filename), Plot2d()
693 {
694  //clear the buffers in case of error while reading the file
695  if(read_all(data_from_file, data_title))
696  {
697  data_from_file.clear();
698  data_title.clear();
699  cerr << "Plot_file::Plot_file: problem in reading file " << filename.c_str() << "." << endl;
700  }
701 }
702 
703 
704 short Plot_file::graph(const string & title_graph, const string & label, const short x,
705  const short y, const short x_start, const short y_start,
706  const short y_end)
708 {
709  if(data_from_file.size())
710  {
711  if(data_from_file[x].Ncols() != data_from_file[y].Ncols())
712  {
713  cerr << "Plot_file::graph: number of rows of xdata and ydata does not match" << endl;
714  return X_Y_DATA_NO_MATCH;
715  }
716 
717  settitle(title_graph.c_str());
718  setxlabel(data_title[x]);
719  setylabel(data_title[y]);
720 
721  string legend;
722  for(int i = y_start; i <= y_end; i++)
723  {
724  ostringstream istr;
725  istr << label << i-y_start+1;
726  legend = istr.str();
727 
728  addcurve((data_from_file[x].SubMatrix(x_start,x_start,1,data_from_file[x].Ncols())
729  & data_from_file[y].SubMatrix(i,i,1,data_from_file[y].Ncols())).t(),
730  legend, DATAPOINTS);
731  }
732  gnuplot();
733  return 0;
734  }
735  else
736  {
737  cerr << "Plot_file::graph: data file buffer is empty." << endl;
738  return PROBLEM_FILE_READING;
739  }
740 }
741 
742 // ---------------------------------------------------------------------------------------------
743 
744 short set_plot2d(const char *title_graph, const char *x_axis_title, const char *y_axis_title,
745  const char *label, LineType_en enLineType, const Matrix &xdata, const Matrix &ydata,
746  int start_y, int end_y)
747 {
748 
749  Plot2d plotgraph;
750  char *legend=0;
751  try
752  {
753  legend = new char[strlen(label)+1];
754  }
755  catch(bad_alloc & e)
756  {
757  cerr << "set_plot2d:: new ran out of memory" << endl;
758  return OUT_OF_MEMORY;
759  }
760 
761  if(xdata.Ncols() != ydata.Ncols())
762  {
763  cerr << "set_plot2d:: number of rows of xdata and ydata does not match" << endl;
764  return X_Y_DATA_NO_MATCH;
765  }
766 
767  plotgraph.settitle(title_graph);
768  plotgraph.setxlabel(x_axis_title);
769  plotgraph.setylabel(y_axis_title);
770 
771  for(int i = start_y; i <= end_y; i++)
772  {
773  snprintf(legend, sizeof(legend), "%s%d", label, i-start_y+1);
774 
775 
776  plotgraph.addcurve((xdata & ydata.SubMatrix(i,i,1,ydata.Ncols())).t(), legend, enLineType);
777  }
778  plotgraph.gnuplot();
779 
780  delete [] legend;
781 
782  return 0;
783 }
784 
785 short set_plot2d(const char *title_graph, const char *x_axis_title, const char *y_axis_title,
786  const vector<char *> label, LineType_en enLineType, const Matrix &xdata,
787  const Matrix &ydata, const vector<int> & data_select)
788 {
789  Plot2d plotgraph;
790 
791  plotgraph.settitle(title_graph);
792  plotgraph.setxlabel(x_axis_title);
793  plotgraph.setylabel(y_axis_title);
794 
795  if(xdata.Ncols() != ydata.Ncols())
796  {
797  cerr << "set_plot2d:: number of rows of xdata and ydata does not match" << endl;
798  return X_Y_DATA_NO_MATCH;
799  }
800  if(data_select.size() != label.size())
801  {
802  cerr << "set_plot2d:: number of labels does not match" << endl;
803  return LABELS_NBR_NO_MATCH;
804  }
805 
806  for(unsigned int i = 0; i < data_select.size(); i++)
807  plotgraph.addcurve((xdata & ydata.SubMatrix(data_select[i],data_select[i],
808  1,ydata.Ncols())).t(), label[i], enLineType);
809  plotgraph.gnuplot();
810 
811  return 0;
812 }
813 
814 
815 short set_plot3d(const Matrix & xyz, const string & title_graph, const string & x_axis_title,
816  const string & y_axis_title, const string & z_axis_title)
817 {
818 
819  Plot3d plotgraph;
820 
821  plotgraph.settitle(title_graph);
822  plotgraph.setxlabel(x_axis_title);
823  plotgraph.setylabel(y_axis_title);
824  plotgraph.setzlabel(z_axis_title);
825  plotgraph.gnuplot(xyz);
826 
827  return 0;
828 }
829 
830 
831 
832 
833 
834 
835 
836 
837 
838 
839 
840 
841 
842