00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #ifndef _GNUPLOT_PIPES_H_
00031 #define _GNUPLOT_PIPES_H_
00032
00033
00034 #include <iostream>
00035 #include <string>
00036 #include <vector>
00037 #include <fstream>
00038 #include <sstream>
00039 #include <stdexcept>
00040 #include <cstdio>
00041 #include <cstdlib>
00042 #include <list>
00043
00044
00045 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
00046
00047 #include <io.h>
00048 #define GP_MAX_TMP_FILES 27 // 27 temporary files it's Microsoft restriction
00049 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
00050
00051 #include <unistd.h>
00052 #define GP_MAX_TMP_FILES 64
00053 #else
00054 #error unsupported or unknown operating system
00055 #endif
00056
00057
00058
00059
00060 class GnuplotException : public std::runtime_error
00061 {
00062 public:
00063 GnuplotException(const std::string &msg) : std::runtime_error(msg){}
00064 };
00065
00066
00067
00068 class Gnuplot
00069 {
00070 private:
00071
00072
00073
00075 FILE *gnucmd;
00077 bool valid;
00079 bool two_dim;
00081 int nplots;
00083 std::string pstyle;
00085 std::string smooth;
00087 std::vector<std::string> tmpfile_list;
00088
00089
00090
00092 static int tmpfile_num;
00094 static std::string m_sGNUPlotFileName;
00096 static std::string m_sGNUPlotPath;
00098 static std::string terminal_std;
00099
00100
00101
00102
00108
00109 void init();
00110
00116
00117 std::string create_tmpfile(std::ofstream &tmp);
00118
00119
00125
00126 static bool get_program_path();
00127
00128
00135
00136 bool file_available(const std::string &filename);
00137
00138
00145
00146 static bool file_exists(const std::string &filename, int mode=0);
00147
00148 public:
00149
00150
00157
00158 static bool set_GNUPlotPath(const std::string &path);
00159
00160
00161
00168
00169 static void set_terminal_std(const std::string &type);
00170
00171
00172
00173
00174
00175
00177 Gnuplot(const std::string &style = "points");
00178
00180 Gnuplot(const std::vector<double> &x,
00181 const std::string &title = "",
00182 const std::string &style = "points",
00183 const std::string &labelx = "x",
00184 const std::string &labely = "y");
00185
00187 Gnuplot(const std::vector<double> &x,
00188 const std::vector<double> &y,
00189 const std::string &title = "",
00190 const std::string &style = "points",
00191 const std::string &labelx = "x",
00192 const std::string &labely = "y");
00193
00195 Gnuplot(const std::vector<double> &x,
00196 const std::vector<double> &y,
00197 const std::vector<double> &z,
00198 const std::string &title = "",
00199 const std::string &style = "points",
00200 const std::string &labelx = "x",
00201 const std::string &labely = "y",
00202 const std::string &labelz = "z");
00203
00205 ~Gnuplot();
00206
00207
00208
00209
00211 Gnuplot& cmd(const std::string &cmdstr);
00212
00219
00220 inline Gnuplot& operator<<(const std::string &cmdstr){
00221 cmd(cmdstr);
00222 return(*this);
00223 }
00224
00225
00226
00227
00228
00229
00231 Gnuplot& showonscreen();
00232
00234 Gnuplot& savetops(const std::string &filename = "gnuplot_output");
00235
00236
00237
00238
00239
00243 Gnuplot& set_style(const std::string &stylestr = "points");
00244
00249 Gnuplot& set_smooth(const std::string &stylestr = "csplines");
00250
00251
00258
00259 inline Gnuplot& unset_smooth(){ smooth = ""; return *this;};
00260
00261
00263 Gnuplot& set_pointsize(const double pointsize = 1.0);
00264
00266 inline Gnuplot& set_grid() {cmd("set grid");return *this;};
00268 inline Gnuplot& unset_grid(){cmd("unset grid");return *this;};
00269
00270
00276
00277 inline Gnuplot& set_multiplot(){cmd("set multiplot") ;return *this;};
00278
00279
00285
00286 inline Gnuplot& unset_multiplot(){cmd("unset multiplot");return *this;};
00287
00288
00289
00291 Gnuplot& set_samples(const int samples = 100);
00293 Gnuplot& set_isosamples(const int isolines = 10);
00294
00295
00301
00302 Gnuplot& set_hidden3d(){cmd("set hidden3d");return *this;};
00303
00304
00310
00311 inline Gnuplot& unset_hidden3d(){cmd("unset hidden3d"); return *this;};
00312
00315 Gnuplot& set_contour(const std::string &position = "base");
00316
00322
00323 inline Gnuplot& unset_contour(){cmd("unset contour");return *this;};
00324
00325
00331
00332 inline Gnuplot& set_surface(){cmd("set surface");return *this;};
00333
00334
00341
00342 inline Gnuplot& unset_surface(){cmd("unset surface"); return *this;}
00343
00344
00347 Gnuplot& set_legend(const std::string &position = "default");
00348
00349
00356
00357 inline Gnuplot& unset_legend(){cmd("unset key"); return *this;}
00358
00359
00365
00366 inline Gnuplot& set_title(const std::string &title = "")
00367 {
00368 std::string cmdstr;
00369 cmdstr = "set title \"";
00370 cmdstr+=title;
00371 cmdstr+="\"";
00372 *this<<cmdstr;
00373 return *this;
00374 }
00375
00376
00383
00384 inline Gnuplot& unset_title(){this->set_title();return *this;}
00385
00386
00388 Gnuplot& set_ylabel(const std::string &label = "x");
00390 Gnuplot& set_xlabel(const std::string &label = "y");
00392 Gnuplot& set_zlabel(const std::string &label = "z");
00393
00395 Gnuplot& set_xrange(const double iFrom,
00396 const double iTo);
00398 Gnuplot& set_yrange(const double iFrom,
00399 const double iTo);
00401 Gnuplot& set_zrange(const double iFrom,
00402 const double iTo);
00408
00409 inline Gnuplot& set_xautoscale(){cmd("set xrange restore");cmd("set autoscale x");return *this;};
00410
00411
00417
00418 inline Gnuplot& set_yautoscale(){cmd("set yrange restore");cmd("set autoscale y");return *this;};
00419
00420
00426
00427 inline Gnuplot& set_zautoscale(){cmd("set zrange restore");cmd("set autoscale z");return *this;};
00428
00429
00431 Gnuplot& set_xlogscale(const double base = 10);
00433 Gnuplot& set_ylogscale(const double base = 10);
00435 Gnuplot& set_zlogscale(const double base = 10);
00436
00437
00443
00444 inline Gnuplot& unset_xlogscale(){cmd("unset logscale x"); return *this;};
00445
00446
00452
00453 inline Gnuplot& unset_ylogscale(){cmd("unset logscale y"); return *this;};
00454
00455
00461
00462 inline Gnuplot& unset_zlogscale(){cmd("unset logscale z"); return *this;};
00463
00464
00466 Gnuplot& set_cbrange(const double iFrom, const double iTo);
00467
00468
00469
00470
00471
00474 Gnuplot& plotfile_x(const std::string &filename,
00475 const unsigned int column = 1,
00476 const std::string &title = "");
00478 template<typename X>
00479 Gnuplot& plot_x(const X& x, const std::string &title = "");
00480
00481
00484 Gnuplot& plotfile_xy(const std::string &filename,
00485 const unsigned int column_x = 1,
00486 const unsigned int column_y = 2,
00487 const std::string &title = "");
00489 template<typename X, typename Y>
00490 Gnuplot& plot_xy(const X& x, const Y& y, const std::string &title = "");
00491
00492
00495 Gnuplot& plotfile_xy_err(const std::string &filename,
00496 const unsigned int column_x = 1,
00497 const unsigned int column_y = 2,
00498 const unsigned int column_dy = 3,
00499 const std::string &title = "");
00501 template<typename X, typename Y, typename E>
00502 Gnuplot& plot_xy_err(const X &x, const Y &y, const E &dy,
00503 const std::string &title = "");
00504
00505
00508 Gnuplot& plotfile_xyz(const std::string &filename,
00509 const unsigned int column_x = 1,
00510 const unsigned int column_y = 2,
00511 const unsigned int column_z = 3,
00512 const std::string &title = "");
00514 template<typename X, typename Y, typename Z>
00515 Gnuplot& plot_xyz(const X &x,
00516 const Y &y,
00517 const Z &z,
00518 const std::string &title = "");
00519
00520
00521
00523 Gnuplot& plot_slope(const double a,
00524 const double b,
00525 const std::string &title = "");
00526
00527
00538 Gnuplot& plot_equation(const std::string &equation,
00539 const std::string &title = "");
00540
00543 Gnuplot& plot_equation3d(const std::string &equation,
00544 const std::string &title = "");
00545
00546
00548 Gnuplot& plot_image(const unsigned char *ucPicBuf,
00549 const unsigned int iWidth,
00550 const unsigned int iHeight,
00551 const std::string &title = "");
00552
00553
00554
00562
00563 inline Gnuplot& replot(void){if (nplots > 0) cmd("replot");return *this;};
00564
00566 Gnuplot& reset_plot();
00567
00569 Gnuplot& reset_all();
00570
00572 void remove_tmpfiles();
00573
00574
00581
00582 inline bool is_valid(){return(valid);};
00583
00584 };
00585
00586
00587
00588
00589
00590 int Gnuplot::tmpfile_num = 0;
00591
00592 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
00593 std::string Gnuplot::m_sGNUPlotFileName = "pgnuplot.exe";
00594 std::string Gnuplot::m_sGNUPlotPath = "C:/program files/gnuplot/bin/";
00595 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
00596 std::string Gnuplot::m_sGNUPlotFileName = "gnuplot";
00597 std::string Gnuplot::m_sGNUPlotPath = "/usr/local/bin/";
00598 #endif
00599
00600 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
00601 std::string Gnuplot::terminal_std = "windows";
00602 #elif ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__)
00603 std::string Gnuplot::terminal_std = "x11";
00604 #elif defined(__APPLE__)
00605 std::string Gnuplot::terminal_std = "aqua";
00606 #endif
00607
00608
00609
00610
00611
00612 inline Gnuplot::Gnuplot(const std::string &style)
00613 :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0)
00614
00615 {
00616 init();
00617 set_style(style);
00618 }
00619
00620
00621
00622
00623
00624 inline Gnuplot::Gnuplot(const std::vector<double> &x,
00625 const std::string &title,
00626 const std::string &style,
00627 const std::string &labelx,
00628 const std::string &labely)
00629 :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0)
00630 {
00631 init();
00632
00633 set_style(style);
00634 set_xlabel(labelx);
00635 set_ylabel(labely);
00636
00637 plot_x(x,title);
00638 }
00639
00640
00641
00642
00643
00644
00645 inline Gnuplot::Gnuplot(const std::vector<double> &x,
00646 const std::vector<double> &y,
00647 const std::string &title,
00648 const std::string &style,
00649 const std::string &labelx,
00650 const std::string &labely)
00651 :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0)
00652 {
00653 init();
00654
00655 set_style(style);
00656 set_xlabel(labelx);
00657 set_ylabel(labely);
00658
00659 plot_xy(x,y,title);
00660 }
00661
00662
00663
00664
00665
00666
00667 inline Gnuplot::Gnuplot(const std::vector<double> &x,
00668 const std::vector<double> &y,
00669 const std::vector<double> &z,
00670 const std::string &title,
00671 const std::string &style,
00672 const std::string &labelx,
00673 const std::string &labely,
00674 const std::string &labelz)
00675 :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0)
00676 {
00677 init();
00678
00679 set_style(style);
00680 set_xlabel(labelx);
00681 set_ylabel(labely);
00682 set_zlabel(labelz);
00683
00684 plot_xyz(x,y,z,title);
00685 }
00686
00687
00688
00689
00691
00692 template<typename X>
00693 Gnuplot& Gnuplot::plot_x(const X& x, const std::string &title)
00694 {
00695 if (x.size() == 0)
00696 {
00697 throw GnuplotException("std::vector too small");
00698 return *this;
00699 }
00700
00701 std::ofstream tmp;
00702 std::string name = create_tmpfile(tmp);
00703 if (name == "")
00704 return *this;
00705
00706
00707
00708
00709 for (unsigned int i = 0; i < x.size(); i++)
00710 tmp << x[i] << std::endl;
00711
00712 tmp.flush();
00713 tmp.close();
00714
00715
00716 plotfile_x(name, 1, title);
00717
00718 return *this;
00719 }
00720
00721
00722
00723
00725
00726 template<typename X, typename Y>
00727 Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title)
00728 {
00729 if (x.size() == 0 || y.size() == 0)
00730 {
00731 throw GnuplotException("std::vectors too small");
00732 return *this;
00733 }
00734
00735 if (x.size() != y.size())
00736 {
00737 throw GnuplotException("Length of the std::vectors differs");
00738 return *this;
00739 }
00740
00741
00742 std::ofstream tmp;
00743 std::string name = create_tmpfile(tmp);
00744 if (name == "")
00745 return *this;
00746
00747
00748
00749
00750 for (unsigned int i = 0; i < x.size(); i++)
00751 tmp << x[i] << " " << y[i] << std::endl;
00752
00753 tmp.flush();
00754 tmp.close();
00755
00756
00757 plotfile_xy(name, 1, 2, title);
00758
00759 return *this;
00760 }
00761
00766 template<typename X, typename Y, typename E>
00767 Gnuplot& Gnuplot::plot_xy_err(const X &x,
00768 const Y &y,
00769 const E &dy,
00770 const std::string &title)
00771 {
00772 if (x.size() == 0 || y.size() == 0 || dy.size() == 0)
00773 {
00774 throw GnuplotException("std::vectors too small");
00775 return *this;
00776 }
00777
00778 if (x.size() != y.size() || y.size() != dy.size())
00779 {
00780 throw GnuplotException("Length of the std::vectors differs");
00781 return *this;
00782 }
00783
00784
00785 std::ofstream tmp;
00786 std::string name = create_tmpfile(tmp);
00787 if (name == "")
00788 return *this;
00789
00790
00791
00792
00793 for (unsigned int i = 0; i < x.size(); i++)
00794 tmp << x[i] << " " << y[i] << " " << dy[i] << std::endl;
00795
00796 tmp.flush();
00797 tmp.close();
00798
00799
00800
00801 plotfile_xy_err(name, 1, 2, 3, title);
00802
00803 return *this;
00804 }
00805
00806
00807
00808
00809
00810
00811 template<typename X, typename Y, typename Z>
00812 Gnuplot& Gnuplot::plot_xyz(const X &x,
00813 const Y &y,
00814 const Z &z,
00815 const std::string &title)
00816 {
00817 if (x.size() == 0 || y.size() == 0 || z.size() == 0)
00818 {
00819 throw GnuplotException("std::vectors too small");
00820 return *this;
00821 }
00822
00823 if (x.size() != y.size() || x.size() != z.size())
00824 {
00825 throw GnuplotException("Length of the std::vectors differs");
00826 return *this;
00827 }
00828
00829
00830 std::ofstream tmp;
00831 std::string name = create_tmpfile(tmp);
00832 if (name == "")
00833 return *this;
00834
00835
00836
00837
00838 for (unsigned int i = 0; i < x.size(); i++)
00839 tmp << x[i] << " " << y[i] << " " << z[i] <<std::endl;
00840
00841 tmp.flush();
00842 tmp.close();
00843
00844
00845 plotfile_xyz(name, 1, 2, 3, title);
00846
00847 return *this;
00848 }
00849
00850
00851
00852
00853
00854
00855
00856 bool Gnuplot::set_GNUPlotPath(const std::string &path)
00857 {
00858
00859 std::string tmp = path + "/" + Gnuplot::m_sGNUPlotFileName;
00860
00861
00862 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
00863 if ( Gnuplot::file_exists(tmp,0) )
00864 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
00865 if ( Gnuplot::file_exists(tmp,1) )
00866 #endif
00867 {
00868 Gnuplot::m_sGNUPlotPath = path;
00869 return true;
00870 }
00871 else
00872 {
00873 Gnuplot::m_sGNUPlotPath.clear();
00874 return false;
00875 }
00876 }
00877
00878
00879
00880
00881
00882
00883
00884 void Gnuplot::set_terminal_std(const std::string &type)
00885 {
00886 #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
00887 if (type.find("x11") != std::string::npos && getenv("DISPLAY") == NULL)
00888 {
00889 throw GnuplotException("Can't find DISPLAY variable");
00890 }
00891 #endif
00892
00893
00894 Gnuplot::terminal_std = type;
00895 return;
00896 }
00897
00898
00899
00900
00901
00902
00903
00904 template <typename Container>
00905 void stringtok (Container &container,
00906 std::string const &in,
00907 const char * const delimiters = " \t\n")
00908 {
00909 const std::string::size_type len = in.length();
00910 std::string::size_type i = 0;
00911
00912 while ( i < len )
00913 {
00914
00915 i = in.find_first_not_of (delimiters, i);
00916
00917 if (i == std::string::npos)
00918 return;
00919
00920
00921 std::string::size_type j = in.find_first_of (delimiters, i);
00922
00923
00924 if (j == std::string::npos)
00925 {
00926 container.push_back (in.substr(i));
00927 return;
00928 }
00929 else
00930 container.push_back (in.substr(i, j-i));
00931
00932
00933 i = j + 1;
00934 }
00935
00936 return;
00937 }
00938
00939
00940
00941
00942
00943
00944 Gnuplot::~Gnuplot()
00945 {
00946
00947
00948
00949 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
00950 if (_pclose(gnucmd) == -1)
00951 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
00952 if (pclose(gnucmd) == -1)
00953 #endif
00954 throw GnuplotException("Problem closing communication to gnuplot");
00955 }
00956
00957
00958
00959
00960
00961
00962 Gnuplot& Gnuplot::reset_plot()
00963 {
00964
00965
00966 nplots = 0;
00967
00968 return *this;
00969 }
00970
00971
00972
00973
00974
00975
00976 Gnuplot& Gnuplot::reset_all()
00977 {
00978
00979
00980 nplots = 0;
00981 cmd("reset");
00982 cmd("clear");
00983 pstyle = "points";
00984 smooth = "";
00985 showonscreen();
00986
00987 return *this;
00988 }
00989
00990
00991
00992
00993
00994
00995 Gnuplot& Gnuplot::set_style(const std::string &stylestr)
00996 {
00997 if (stylestr.find("lines") == std::string::npos &&
00998 stylestr.find("points") == std::string::npos &&
00999 stylestr.find("linespoints") == std::string::npos &&
01000 stylestr.find("impulses") == std::string::npos &&
01001 stylestr.find("dots") == std::string::npos &&
01002 stylestr.find("steps") == std::string::npos &&
01003 stylestr.find("fsteps") == std::string::npos &&
01004 stylestr.find("histeps") == std::string::npos &&
01005 stylestr.find("boxes") == std::string::npos &&
01006 stylestr.find("filledcurves") == std::string::npos &&
01007 stylestr.find("histograms") == std::string::npos )
01008
01009
01010
01011
01012
01013
01014
01015
01016
01017
01018
01019
01020
01021
01022
01023
01024
01025 {
01026 pstyle = std::string("points");
01027 }
01028 else
01029 {
01030 pstyle = stylestr;
01031 }
01032
01033 return *this;
01034 }
01035
01036
01037
01038
01039
01040
01041 Gnuplot& Gnuplot::set_smooth(const std::string &stylestr)
01042 {
01043 if (stylestr.find("unique") == std::string::npos &&
01044 stylestr.find("frequency") == std::string::npos &&
01045 stylestr.find("csplines") == std::string::npos &&
01046 stylestr.find("acsplines") == std::string::npos &&
01047 stylestr.find("bezier") == std::string::npos &&
01048 stylestr.find("sbezier") == std::string::npos )
01049 {
01050 smooth = "";
01051 }
01052 else
01053 {
01054 smooth = stylestr;
01055 }
01056
01057 return *this;
01058 }
01059
01060
01061
01062
01063
01064
01065 Gnuplot& Gnuplot::showonscreen()
01066 {
01067 cmd("set output");
01068 cmd("set terminal " + Gnuplot::terminal_std);
01069
01070 return *this;
01071 }
01072
01073
01074
01075
01076
01077 Gnuplot& Gnuplot::savetops(const std::string &filename)
01078 {
01079 cmd("set terminal postscript color");
01080
01081 std::ostringstream cmdstr;
01082 cmdstr << "set output \"" << filename << ".ps\"";
01083 cmd(cmdstr.str());
01084
01085 return *this;
01086 }
01087
01088
01089
01090
01091
01092 Gnuplot& Gnuplot::set_legend(const std::string &position)
01093 {
01094 std::ostringstream cmdstr;
01095 cmdstr << "set key " << position;
01096
01097 cmd(cmdstr.str());
01098
01099 return *this;
01100 }
01101
01102
01103
01104
01105
01106 Gnuplot& Gnuplot::set_xlogscale(const double base)
01107 {
01108 std::ostringstream cmdstr;
01109
01110 cmdstr << "set logscale x " << base;
01111 cmd(cmdstr.str());
01112
01113 return *this;
01114 }
01115
01116
01117
01118
01119
01120 Gnuplot& Gnuplot::set_ylogscale(const double base)
01121 {
01122 std::ostringstream cmdstr;
01123
01124 cmdstr << "set logscale y " << base;
01125 cmd(cmdstr.str());
01126
01127 return *this;
01128 }
01129
01130
01131
01132
01133
01134 Gnuplot& Gnuplot::set_zlogscale(const double base)
01135 {
01136 std::ostringstream cmdstr;
01137
01138 cmdstr << "set logscale z " << base;
01139 cmd(cmdstr.str());
01140
01141 return *this;
01142 }
01143
01144
01145
01146
01147
01148 Gnuplot& Gnuplot::set_pointsize(const double pointsize)
01149 {
01150 std::ostringstream cmdstr;
01151 cmdstr << "set pointsize " << pointsize;
01152 cmd(cmdstr.str());
01153
01154 return *this;
01155 }
01156
01157
01158
01159
01160
01161 Gnuplot& Gnuplot::set_samples(const int samples)
01162 {
01163 std::ostringstream cmdstr;
01164 cmdstr << "set samples " << samples;
01165 cmd(cmdstr.str());
01166
01167 return *this;
01168 }
01169
01170
01171
01172
01173
01174
01175 Gnuplot& Gnuplot::set_isosamples(const int isolines)
01176 {
01177 std::ostringstream cmdstr;
01178 cmdstr << "set isosamples " << isolines;
01179 cmd(cmdstr.str());
01180
01181 return *this;
01182 }
01183
01184
01185
01186
01187
01188
01189
01190 Gnuplot& Gnuplot::set_contour(const std::string &position)
01191 {
01192 if (position.find("base") == std::string::npos &&
01193 position.find("surface") == std::string::npos &&
01194 position.find("both") == std::string::npos )
01195 {
01196 cmd("set contour base");
01197 }
01198 else
01199 {
01200 cmd("set contour " + position);
01201 }
01202
01203 return *this;
01204 }
01205
01206
01207
01208
01209
01210
01211 Gnuplot& Gnuplot::set_xlabel(const std::string &label)
01212 {
01213 std::ostringstream cmdstr;
01214
01215 cmdstr << "set xlabel \"" << label << "\"";
01216 cmd(cmdstr.str());
01217
01218 return *this;
01219 }
01220
01221
01222
01223
01224 Gnuplot& Gnuplot::set_ylabel(const std::string &label)
01225 {
01226 std::ostringstream cmdstr;
01227
01228 cmdstr << "set ylabel \"" << label << "\"";
01229 cmd(cmdstr.str());
01230
01231 return *this;
01232 }
01233
01234
01235
01236
01237 Gnuplot& Gnuplot::set_zlabel(const std::string &label)
01238 {
01239 std::ostringstream cmdstr;
01240
01241 cmdstr << "set zlabel \"" << label << "\"";
01242 cmd(cmdstr.str());
01243
01244 return *this;
01245 }
01246
01247
01248
01249
01250
01251
01252 Gnuplot& Gnuplot::set_xrange(const double iFrom,
01253 const double iTo)
01254 {
01255 std::ostringstream cmdstr;
01256
01257 cmdstr << "set xrange[" << iFrom << ":" << iTo << "]";
01258 cmd(cmdstr.str());
01259
01260 return *this;
01261 }
01262
01263
01264
01265
01266 Gnuplot& Gnuplot::set_yrange(const double iFrom,
01267 const double iTo)
01268 {
01269 std::ostringstream cmdstr;
01270
01271 cmdstr << "set yrange[" << iFrom << ":" << iTo << "]";
01272 cmd(cmdstr.str());
01273
01274 return *this;
01275 }
01276
01277
01278
01279
01280 Gnuplot& Gnuplot::set_zrange(const double iFrom,
01281 const double iTo)
01282 {
01283 std::ostringstream cmdstr;
01284
01285 cmdstr << "set zrange[" << iFrom << ":" << iTo << "]";
01286 cmd(cmdstr.str());
01287
01288 return *this;
01289 }
01290
01291
01292
01293
01294
01295 Gnuplot& Gnuplot::set_cbrange(const double iFrom,
01296 const double iTo)
01297 {
01298 std::ostringstream cmdstr;
01299
01300 cmdstr << "set cbrange[" << iFrom << ":" << iTo << "]";
01301 cmd(cmdstr.str());
01302
01303 return *this;
01304 }
01305
01306
01307
01308
01309
01310
01311 Gnuplot& Gnuplot::plot_slope(const double a,
01312 const double b,
01313 const std::string &title)
01314 {
01315 std::ostringstream cmdstr;
01316
01317
01318
01319 if (nplots > 0 && two_dim == true)
01320 cmdstr << "replot ";
01321 else
01322 cmdstr << "plot ";
01323
01324 cmdstr << a << " * x + " << b << " title \"";
01325
01326 if (title == "")
01327 cmdstr << "f(x) = " << a << " * x + " << b;
01328 else
01329 cmdstr << title;
01330
01331 cmdstr << "\" with " << pstyle;
01332
01333
01334
01335
01336 cmd(cmdstr.str());
01337
01338 return *this;
01339 }
01340
01341
01342
01343
01344
01345 Gnuplot& Gnuplot::plot_equation(const std::string &equation,
01346 const std::string &title)
01347 {
01348 std::ostringstream cmdstr;
01349
01350
01351
01352 if (nplots > 0 && two_dim == true)
01353 cmdstr << "replot ";
01354 else
01355 cmdstr << "plot ";
01356
01357 cmdstr << equation << " title \"";
01358
01359 if (title == "")
01360 cmdstr << "f(x) = " << equation;
01361 else
01362 cmdstr << title;
01363
01364 cmdstr << "\" with " << pstyle;
01365
01366
01367
01368
01369 cmd(cmdstr.str());
01370
01371 return *this;
01372 }
01373
01374
01375
01376
01377
01378 Gnuplot& Gnuplot::plot_equation3d(const std::string &equation,
01379 const std::string &title)
01380 {
01381 std::ostringstream cmdstr;
01382
01383
01384
01385 if (nplots > 0 && two_dim == false)
01386 cmdstr << "replot ";
01387 else
01388 cmdstr << "splot ";
01389
01390 cmdstr << equation << " title \"";
01391
01392 if (title == "")
01393 cmdstr << "f(x,y) = " << equation;
01394 else
01395 cmdstr << title;
01396
01397 cmdstr << "\" with " << pstyle;
01398
01399
01400
01401
01402 cmd(cmdstr.str());
01403
01404 return *this;
01405 }
01406
01407
01408
01409
01410
01411
01412 Gnuplot& Gnuplot::plotfile_x(const std::string &filename,
01413 const unsigned int column,
01414 const std::string &title)
01415 {
01416
01417
01418
01419 file_available(filename);
01420
01421
01422 std::ostringstream cmdstr;
01423
01424
01425
01426 if (nplots > 0 && two_dim == true)
01427 cmdstr << "replot ";
01428 else
01429 cmdstr << "plot ";
01430
01431 cmdstr << "\"" << filename << "\" using " << column;
01432
01433 if (title == "")
01434 cmdstr << " notitle ";
01435 else
01436 cmdstr << " title \"" << title << "\" ";
01437
01438 if(smooth == "")
01439 cmdstr << "with " << pstyle;
01440 else
01441 cmdstr << "smooth " << smooth;
01442
01443
01444
01445
01446 cmd(cmdstr.str());
01447
01448 return *this;
01449 }
01450
01451
01452
01453
01454
01455
01456
01457 Gnuplot& Gnuplot::plotfile_xy(const std::string &filename,
01458 const unsigned int column_x,
01459 const unsigned int column_y,
01460 const std::string &title)
01461 {
01462
01463
01464
01465 file_available(filename);
01466
01467
01468 std::ostringstream cmdstr;
01469
01470
01471
01472 if (nplots > 0 && two_dim == true)
01473 cmdstr << "replot ";
01474 else
01475 cmdstr << "plot ";
01476
01477 cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y;
01478
01479 if (title == "")
01480 cmdstr << " notitle ";
01481 else
01482 cmdstr << " title \"" << title << "\" ";
01483
01484 if(smooth == "")
01485 cmdstr << "with " << pstyle;
01486 else
01487 cmdstr << "smooth " << smooth;
01488
01489
01490
01491
01492 cmd(cmdstr.str());
01493
01494 return *this;
01495 }
01496
01497
01498
01499
01500
01501
01502 Gnuplot& Gnuplot::plotfile_xy_err(const std::string &filename,
01503 const unsigned int column_x,
01504 const unsigned int column_y,
01505 const unsigned int column_dy,
01506 const std::string &title)
01507 {
01508
01509
01510
01511 file_available(filename);
01512
01513 std::ostringstream cmdstr;
01514
01515
01516
01517 if (nplots > 0 && two_dim == true)
01518 cmdstr << "replot ";
01519 else
01520 cmdstr << "plot ";
01521
01522 cmdstr << "\"" << filename << "\" using "
01523 << column_x << ":" << column_y << ":" << column_dy
01524 << " with errorbars ";
01525
01526 if (title == "")
01527 cmdstr << " notitle ";
01528 else
01529 cmdstr << " title \"" << title << "\" ";
01530
01531
01532
01533
01534 cmd(cmdstr.str());
01535
01536 return *this;
01537 }
01538
01539
01540
01541
01542
01543
01544 Gnuplot& Gnuplot::plotfile_xyz(const std::string &filename,
01545 const unsigned int column_x,
01546 const unsigned int column_y,
01547 const unsigned int column_z,
01548 const std::string &title)
01549 {
01550
01551
01552
01553 file_available(filename);
01554
01555 std::ostringstream cmdstr;
01556
01557
01558
01559 if (nplots > 0 && two_dim == false)
01560 cmdstr << "replot ";
01561 else
01562 cmdstr << "splot ";
01563
01564 cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y
01565 << ":" << column_z;
01566
01567 if (title == "")
01568 cmdstr << " notitle with " << pstyle;
01569 else
01570 cmdstr << " title \"" << title << "\" with " << pstyle;
01571
01572
01573
01574
01575 cmd(cmdstr.str());
01576
01577 return *this;
01578 }
01579
01580
01581
01582
01583
01585
01586 Gnuplot& Gnuplot::plot_image(const unsigned char * ucPicBuf,
01587 const unsigned int iWidth,
01588 const unsigned int iHeight,
01589 const std::string &title)
01590 {
01591 std::ofstream tmp;
01592 std::string name = create_tmpfile(tmp);
01593 if (name == "")
01594 return *this;
01595
01596
01597
01598
01599 int iIndex = 0;
01600 for(int iRow = 0; iRow < iHeight; iRow++)
01601 {
01602 for(int iColumn = 0; iColumn < iWidth; iColumn++)
01603 {
01604 tmp << iColumn << " " << iRow << " "
01605 << static_cast<float>(ucPicBuf[iIndex++]) << std::endl;
01606 }
01607 }
01608
01609 tmp.flush();
01610 tmp.close();
01611
01612
01613 std::ostringstream cmdstr;
01614
01615
01616
01617 if (nplots > 0 && two_dim == true)
01618 cmdstr << "replot ";
01619 else
01620 cmdstr << "plot ";
01621
01622 if (title == "")
01623 cmdstr << "\"" << name << "\" with image";
01624 else
01625 cmdstr << "\"" << name << "\" title \"" << title << "\" with image";
01626
01627
01628
01629
01630 cmd(cmdstr.str());
01631
01632 return *this;
01633 }
01634
01635
01636
01637
01638
01639
01640
01641 Gnuplot& Gnuplot::cmd(const std::string &cmdstr)
01642 {
01643 if( !(valid) )
01644 {
01645 return *this;
01646 }
01647
01648
01649
01650
01651
01652
01653
01654 fputs( (cmdstr+"\n").c_str(), gnucmd );
01655
01656
01657
01658
01659
01660
01661 fflush(gnucmd);
01662
01663
01664 if( cmdstr.find("replot") != std::string::npos )
01665 {
01666 return *this;
01667 }
01668 else if( cmdstr.find("splot") != std::string::npos )
01669 {
01670 two_dim = false;
01671 nplots++;
01672 }
01673 else if( cmdstr.find("plot") != std::string::npos )
01674 {
01675 two_dim = true;
01676 nplots++;
01677 }
01678
01679 return *this;
01680 }
01681
01682
01683
01684
01685
01686
01687
01688 void Gnuplot::init()
01689 {
01690
01691
01692
01693
01694 #if ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__)
01695 if (getenv("DISPLAY") == NULL)
01696 {
01697 valid = false;
01698 throw GnuplotException("Can't find DISPLAY variable");
01699 }
01700 #endif
01701
01702
01703
01704 if (!Gnuplot::get_program_path())
01705 {
01706 valid = false;
01707 throw GnuplotException("Can't find gnuplot");
01708 }
01709
01710
01711
01712
01713
01714 std::string tmp = Gnuplot::m_sGNUPlotPath + "/" +
01715 Gnuplot::m_sGNUPlotFileName;
01716
01717
01718
01719
01720
01721
01722 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
01723 gnucmd = _popen(tmp.c_str(),"w");
01724 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
01725 gnucmd = popen(tmp.c_str(),"w");
01726 #endif
01727
01728
01729
01730
01731 if (!gnucmd)
01732 {
01733 valid = false;
01734 throw GnuplotException("Couldn't open connection to gnuplot");
01735 }
01736
01737 nplots = 0;
01738 valid = true;
01739 smooth = "";
01740
01741
01742 showonscreen();
01743
01744 return;
01745 }
01746
01747
01748
01749
01750
01751
01752 bool Gnuplot::get_program_path()
01753 {
01754
01755
01756
01757 std::string tmp = Gnuplot::m_sGNUPlotPath + "/" +
01758 Gnuplot::m_sGNUPlotFileName;
01759
01760 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
01761 if ( Gnuplot::file_exists(tmp,0) )
01762 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
01763 if ( Gnuplot::file_exists(tmp,1) )
01764 #endif
01765 {
01766 return true;
01767 }
01768
01769
01770
01771
01772
01773 char *path;
01774
01775 path = getenv("PATH");
01776
01777
01778 if (path == NULL)
01779 {
01780 throw GnuplotException("Path is not set");
01781 return false;
01782 }
01783 else
01784 {
01785 std::list<std::string> ls;
01786
01787
01788 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
01789 stringtok(ls,path,";");
01790 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
01791 stringtok(ls,path,":");
01792 #endif
01793
01794
01795 for (std::list<std::string>::const_iterator i = ls.begin();
01796 i != ls.end(); ++i)
01797 {
01798 tmp = (*i) + "/" + Gnuplot::m_sGNUPlotFileName;
01799 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
01800 if ( Gnuplot::file_exists(tmp,0) )
01801 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
01802 if ( Gnuplot::file_exists(tmp,1) )
01803 #endif
01804 {
01805 Gnuplot::m_sGNUPlotPath = *i;
01806 return true;
01807 }
01808 }
01809
01810 tmp = "Can't find gnuplot neither in PATH nor in \"" +
01811 Gnuplot::m_sGNUPlotPath + "\"";
01812 throw GnuplotException(tmp);
01813
01814 Gnuplot::m_sGNUPlotPath = "";
01815 return false;
01816 }
01817 }
01818
01819
01820
01821
01822
01823
01824
01825 bool Gnuplot::file_exists(const std::string &filename, int mode)
01826 {
01827 if ( mode < 0 || mode > 7)
01828 {
01829 throw std::runtime_error("In function \"Gnuplot::file_exists\": mode\
01830 has to be an integer between 0 and 7");
01831 return false;
01832 }
01833
01834
01835
01836
01837
01838
01839
01840
01841
01842
01843
01844 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
01845 if (_access(filename.c_str(), mode) == 0)
01846 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
01847 if (access(filename.c_str(), mode) == 0)
01848 #endif
01849 {
01850 return true;
01851 }
01852 else
01853 {
01854 return false;
01855 }
01856
01857 }
01858
01859 bool Gnuplot::file_available(const std::string &filename){
01860 std::ostringstream except;
01861 if( Gnuplot::file_exists(filename,0) )
01862 {
01863 if( !(Gnuplot::file_exists(filename,4)) ){
01864 except << "No read permission for File \"" << filename << "\"";
01865 throw GnuplotException( except.str() );
01866 return false;
01867 }
01868 }
01869 else{
01870 except << "File \"" << filename << "\" does not exist";
01871 throw GnuplotException( except.str() );
01872 return false;
01873 }
01874 }
01875
01876
01877
01878
01879
01880
01881
01882 std::string Gnuplot::create_tmpfile(std::ofstream &tmp)
01883 {
01884
01885 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
01886 char name[] = "gnuplotiXXXXXX";
01887 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
01888 char name[] = "/tmp/gnuplotiXXXXXX";
01889 #endif
01890
01891
01892
01893
01894 if (Gnuplot::tmpfile_num == GP_MAX_TMP_FILES - 1)
01895 {
01896 std::ostringstream except;
01897 except << "Maximum number of temporary files reached ("
01898 << GP_MAX_TMP_FILES << "): cannot open more files" << std::endl;
01899
01900 throw GnuplotException( except.str() );
01901 return "";
01902 }
01903
01904
01905
01906
01907
01908
01909
01910
01911
01912
01913
01914
01915
01916
01917
01918 #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
01919 if (_mktemp(name) == NULL)
01920 #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
01921 if (mkstemp(name) == -1)
01922 #endif
01923 {
01924 std::ostringstream except;
01925 except << "Cannot create temporary file \"" << name << "\"";
01926 throw GnuplotException(except.str());
01927 return "";
01928 }
01929
01930 tmp.open(name);
01931 if (tmp.bad())
01932 {
01933 std::ostringstream except;
01934 except << "Cannot create temporary file \"" << name << "\"";
01935 throw GnuplotException(except.str());
01936 return "";
01937 }
01938
01939
01940
01941
01942 tmpfile_list.push_back(name);
01943 Gnuplot::tmpfile_num++;
01944
01945 return name;
01946 }
01947
01948 void Gnuplot::remove_tmpfiles(){
01949 if ((tmpfile_list).size() > 0)
01950 {
01951 for (unsigned int i = 0; i < tmpfile_list.size(); i++)
01952 remove( tmpfile_list[i].c_str() );
01953
01954 Gnuplot::tmpfile_num -= tmpfile_list.size();
01955 }
01956 }
01957 #endif