Created
June 30, 2013 15:23
-
-
Save zhaojkun/5895566 to your computer and use it in GitHub Desktop.
对http://code.google.com/p/gnuplot-cpp/ 上的库函数进行了适当的修改。即将init函数中的gnuplot.exe的路径进行了固定,不知道什么原因,作者的函数在我电脑上不能成功使用,所以指定先在自己电脑上将gnuplot的路径添加到path环境变量中,然后在程序中直接调用gnuplot就行了。
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| //////////////////////////////////////////////////////////////////////////////// | |
| /// | |
| /// \brief A C++ interface to gnuplot. | |
| /// | |
| /// | |
| /// The interface uses pipes and so won't run on a system that doesn't have | |
| /// POSIX pipe support Tested on Windows (MinGW and Visual C++) and Linux (GCC) | |
| /// | |
| /// Version history: | |
| /// 0. C interface | |
| /// by N. Devillard (27/01/03) | |
| /// 1. C++ interface: direct translation from the C interface | |
| /// by Rajarshi Guha (07/03/03) | |
| /// 2. corrections for Win32 compatibility | |
| /// by V. Chyzhdzenka (20/05/03) | |
| /// 3. some member functions added, corrections for Win32 and Linux | |
| /// compatibility | |
| /// by M. Burgis (10/03/08) | |
| /// | |
| /// Requirements: | |
| /// * gnuplot has to be installed (http://www.gnuplot.info/download.html) | |
| /// * for Windows: set Path-Variable for Gnuplot path | |
| /// (e.g. C:/program files/gnuplot/bin) | |
| /// or set Gnuplot path with: | |
| /// Gnuplot::set_GNUPlotPath(const std::string &path); | |
| /// | |
| //////////////////////////////////////////////////////////////////////////////// | |
| #ifndef _GNUPLOT_PIPES_H_ | |
| #define _GNUPLOT_PIPES_H_ | |
| #include <iostream> | |
| #include <string> | |
| #include <vector> | |
| #include <fstream> | |
| #include <sstream> // for std::ostringstream | |
| #include <stdexcept> | |
| #include <cstdio> | |
| #include <cstdlib> // for getenv() | |
| #include <list> // for std::list | |
| //defined for 32 and 64-bit environments | |
| #include <io.h> // for _access(), _mktemp() | |
| #define GP_MAX_TMP_FILES 27 // 27 temporary files it's Microsoft restriction | |
| //declare classes in global namespace | |
| class GnuplotException : public std::runtime_error | |
| { | |
| public: | |
| GnuplotException(const std::string &msg) : std::runtime_error(msg){} | |
| }; | |
| class Gnuplot | |
| { | |
| private: | |
| //---------------------------------------------------------------------------------- | |
| // member data | |
| ///\brief pointer to the stream that can be used to write to the pipe | |
| FILE *gnucmd; | |
| ///\brief validation of gnuplot session | |
| bool valid; | |
| ///\brief true = 2d, false = 3d | |
| bool two_dim; | |
| ///\brief number of plots in session | |
| int nplots; | |
| ///\brief functions and data are displayed in a defined styles | |
| std::string pstyle; | |
| ///\brief interpolate and approximate data in defined styles (e.g. spline) | |
| std::string smooth; | |
| ///\brief list of created tmpfiles | |
| std::vector<std::string> tmpfile_list; | |
| //---------------------------------------------------------------------------------- | |
| // static data | |
| ///\brief number of all tmpfiles (number of tmpfiles restricted) | |
| static int tmpfile_num; | |
| ///\brief name of executed GNUPlot file | |
| static std::string m_sGNUPlotFileName; | |
| ///\brief gnuplot path | |
| static std::string m_sGNUPlotPath; | |
| ///\brief standart terminal, used by showonscreen | |
| static std::string terminal_std; | |
| //---------------------------------------------------------------------------------- | |
| // member functions (auxiliary functions) | |
| // --------------------------------------------------- | |
| ///\brief get_program_path(); and popen(); | |
| /// | |
| /// \param --> void | |
| /// | |
| /// \return <-- void | |
| // --------------------------------------------------- | |
| void init(); | |
| // --------------------------------------------------- | |
| ///\brief creates tmpfile and returns its name | |
| /// | |
| /// \param tmp --> points to the tempfile | |
| /// | |
| /// \return <-- the name of the tempfile | |
| // --------------------------------------------------- | |
| std::string create_tmpfile(std::ofstream &tmp); | |
| //---------------------------------------------------------------------------------- | |
| ///\brief gnuplot path found? | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- found the gnuplot path (yes == true, no == false) | |
| // --------------------------------------------------------------------------------- | |
| static bool get_program_path(); | |
| // --------------------------------------------------------------------------------- | |
| ///\brief checks if file is available | |
| /// | |
| /// \param filename --> the filename | |
| /// \param mode --> the mode [optional,default value = 0] | |
| /// | |
| /// \return file exists (yes == true, no == false) | |
| // --------------------------------------------------------------------------------- | |
| bool file_available(const std::string &filename); | |
| // --------------------------------------------------------------------------------- | |
| ///\brief checks if file exists | |
| /// | |
| /// \param filename --> the filename | |
| /// \param mode --> the mode [optional,default value = 0] | |
| /// | |
| /// \return file exists (yes == true, no == false) | |
| // --------------------------------------------------------------------------------- | |
| static bool file_exists(const std::string &filename, int mode=0); | |
| public: | |
| // ---------------------------------------------------------------------------- | |
| /// \brief optional function: set Gnuplot path manual | |
| /// attention: for windows: path with slash '/' not backslash '\' | |
| /// | |
| /// \param path --> the gnuplot path | |
| /// | |
| /// \return true on success, false otherwise | |
| // ---------------------------------------------------------------------------- | |
| static bool set_GNUPlotPath(const std::string &path); | |
| // ---------------------------------------------------------------------------- | |
| /// optional: set standart terminal, used by showonscreen | |
| /// defaults: Windows - win, Linux - x11, Mac - aqua | |
| /// | |
| /// \param type --> the terminal type | |
| /// | |
| /// \return --- | |
| // ---------------------------------------------------------------------------- | |
| static void set_terminal_std(const std::string &type); | |
| //----------------------------------------------------------------------------- | |
| // constructors | |
| // ---------------------------------------------------------------------------- | |
| ///\brief set a style during construction | |
| Gnuplot(const std::string &style = "points"); | |
| /// plot a single std::vector at one go | |
| Gnuplot(const std::vector<double> &x, | |
| const std::string &title = "", | |
| const std::string &style = "points", | |
| const std::string &labelx = "x", | |
| const std::string &labely = "y"); | |
| /// plot pairs std::vector at one go | |
| Gnuplot(const std::vector<double> &x, | |
| const std::vector<double> &y, | |
| const std::string &title = "", | |
| const std::string &style = "points", | |
| const std::string &labelx = "x", | |
| const std::string &labely = "y"); | |
| /// plot triples std::vector at one go | |
| Gnuplot(const std::vector<double> &x, | |
| const std::vector<double> &y, | |
| const std::vector<double> &z, | |
| const std::string &title = "", | |
| const std::string &style = "points", | |
| const std::string &labelx = "x", | |
| const std::string &labely = "y", | |
| const std::string &labelz = "z"); | |
| /// destructor: needed to delete temporary files | |
| ~Gnuplot(); | |
| //---------------------------------------------------------------------------------- | |
| /// send a command to gnuplot | |
| Gnuplot& cmd(const std::string &cmdstr); | |
| // --------------------------------------------------------------------------------- | |
| ///\brief Sends a command to an active gnuplot session, identical to cmd() | |
| /// send a command to gnuplot using the << operator | |
| /// | |
| /// \param cmdstr --> the command string | |
| /// | |
| /// \return <-- a reference to the gnuplot object | |
| // --------------------------------------------------------------------------------- | |
| inline Gnuplot& operator<<(const std::string &cmdstr){ | |
| cmd(cmdstr); | |
| return(*this); | |
| } | |
| //---------------------------------------------------------------------------------- | |
| // show on screen or write to file | |
| /// sets terminal type to terminal_std | |
| Gnuplot& showonscreen(); // window output is set by default (win/x11/aqua) | |
| /// saves a gnuplot session to a postscript file, filename without extension | |
| Gnuplot& savetops(const std::string &filename = "gnuplot_output"); | |
| //---------------------------------------------------------------------------------- | |
| // set and unset | |
| /// set line style (some of these styles require additional information): | |
| /// lines, points, linespoints, impulses, dots, steps, fsteps, histeps, | |
| /// boxes, histograms, filledcurves | |
| Gnuplot& set_style(const std::string &stylestr = "points"); | |
| /// interpolation and approximation of data, arguments: | |
| /// csplines, bezier, acsplines (for data values > 0), sbezier, unique, frequency | |
| /// (works only with plot_x, plot_xy, plotfile_x, plotfile_xy | |
| /// (if smooth is set, set_style has no effekt on data plotting) | |
| Gnuplot& set_smooth(const std::string &stylestr = "csplines"); | |
| // ---------------------------------------------------------------------- | |
| /// \brief unset smooth | |
| /// attention: smooth is not set by default | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- a reference to a gnuplot object | |
| // ---------------------------------------------------------------------- | |
| inline Gnuplot& unset_smooth(){ smooth = ""; return *this;}; | |
| /// scales the size of the points used in plots | |
| Gnuplot& set_pointsize(const double pointsize = 1.0); | |
| /// turns grid on/off | |
| inline Gnuplot& set_grid() {cmd("set grid");return *this;}; | |
| /// grid is not set by default | |
| inline Gnuplot& unset_grid(){cmd("unset grid");return *this;}; | |
| // ----------------------------------------------- | |
| /// set the mulitplot mode | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& set_multiplot(){cmd("set multiplot") ;return *this;}; | |
| // ----------------------------------------------- | |
| /// unsets the mulitplot mode | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& unset_multiplot(){cmd("unset multiplot");return *this;}; | |
| /// set sampling rate of functions, or for interpolating data | |
| Gnuplot& set_samples(const int samples = 100); | |
| /// set isoline density (grid) for plotting functions as surfaces (for 3d plots) | |
| Gnuplot& set_isosamples(const int isolines = 10); | |
| // -------------------------------------------------------------------------- | |
| /// enables/disables hidden line removal for surface plotting (for 3d plot) | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // -------------------------------------------------------------------------- | |
| Gnuplot& set_hidden3d(){cmd("set hidden3d");return *this;}; | |
| // --------------------------------------------------------------------------- | |
| /// hidden3d is not set by default | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // --------------------------------------------------------------------------- | |
| inline Gnuplot& unset_hidden3d(){cmd("unset hidden3d"); return *this;}; | |
| /// enables/disables contour drawing for surfaces (for 3d plot) | |
| /// base, surface, both | |
| Gnuplot& set_contour(const std::string &position = "base"); | |
| // -------------------------------------------------------------------------- | |
| /// contour is not set by default, it disables contour drawing for surfaces | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ------------------------------------------------------------------ | |
| inline Gnuplot& unset_contour(){cmd("unset contour");return *this;}; | |
| // ------------------------------------------------------------ | |
| /// enables/disables the display of surfaces (for 3d plot) | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ------------------------------------------------------------------ | |
| inline Gnuplot& set_surface(){cmd("set surface");return *this;}; | |
| // ---------------------------------------------------------- | |
| /// surface is set by default, | |
| /// it disables the display of surfaces (for 3d plot) | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ------------------------------------------------------------------ | |
| inline Gnuplot& unset_surface(){cmd("unset surface"); return *this;} | |
| /// switches legend on/off | |
| /// position: inside/outside, left/center/right, top/center/bottom, nobox/box | |
| Gnuplot& set_legend(const std::string &position = "default"); | |
| // ------------------------------------------------------------------ | |
| /// \brief Switches legend off | |
| /// attention:legend is set by default | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ------------------------------------------------------------------ | |
| inline Gnuplot& unset_legend(){cmd("unset key"); return *this;} | |
| // ----------------------------------------------------------------------- | |
| /// \brief sets and clears the title of a gnuplot session | |
| /// | |
| /// \param title --> the title of the plot [optional, default == ""] | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------------------------------- | |
| inline Gnuplot& set_title(const std::string &title = "") | |
| { | |
| std::string cmdstr; | |
| cmdstr = "set title \""; | |
| cmdstr+=title; | |
| cmdstr+="\""; | |
| *this<<cmdstr; | |
| return *this; | |
| } | |
| //---------------------------------------------------------------------------------- | |
| ///\brief Clears the title of a gnuplot session | |
| /// The title is not set by default. | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // --------------------------------------------------------------------------------- | |
| inline Gnuplot& unset_title(){this->set_title();return *this;} | |
| /// set x axis label | |
| Gnuplot& set_ylabel(const std::string &label = "x"); | |
| /// set y axis label | |
| Gnuplot& set_xlabel(const std::string &label = "y"); | |
| /// set z axis label | |
| Gnuplot& set_zlabel(const std::string &label = "z"); | |
| /// set axis - ranges | |
| Gnuplot& set_xrange(const double iFrom, | |
| const double iTo); | |
| /// set y-axis - ranges | |
| Gnuplot& set_yrange(const double iFrom, | |
| const double iTo); | |
| /// set z-axis - ranges | |
| Gnuplot& set_zrange(const double iFrom, | |
| const double iTo); | |
| /// autoscale axis (set by default) of xaxis | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& set_xautoscale(){cmd("set xrange restore");cmd("set autoscale x");return *this;}; | |
| // ----------------------------------------------- | |
| /// autoscale axis (set by default) of yaxis | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& set_yautoscale(){cmd("set yrange restore");cmd("set autoscale y");return *this;}; | |
| // ----------------------------------------------- | |
| /// autoscale axis (set by default) of zaxis | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& set_zautoscale(){cmd("set zrange restore");cmd("set autoscale z");return *this;}; | |
| /// turns on/off log scaling for the specified xaxis (logscale is not set by default) | |
| Gnuplot& set_xlogscale(const double base = 10); | |
| /// turns on/off log scaling for the specified yaxis (logscale is not set by default) | |
| Gnuplot& set_ylogscale(const double base = 10); | |
| /// turns on/off log scaling for the specified zaxis (logscale is not set by default) | |
| Gnuplot& set_zlogscale(const double base = 10); | |
| // ----------------------------------------------- | |
| /// turns off log scaling for the x axis | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& unset_xlogscale(){cmd("unset logscale x"); return *this;}; | |
| // ----------------------------------------------- | |
| /// turns off log scaling for the y axis | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& unset_ylogscale(){cmd("unset logscale y"); return *this;}; | |
| // ----------------------------------------------- | |
| /// turns off log scaling for the z axis | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return <-- reference to the gnuplot object | |
| // ----------------------------------------------- | |
| inline Gnuplot& unset_zlogscale(){cmd("unset logscale z"); return *this;}; | |
| /// set palette range (autoscale by default) | |
| Gnuplot& set_cbrange(const double iFrom, const double iTo); | |
| //---------------------------------------------------------------------------------- | |
| // plot | |
| /// plot a single std::vector: x | |
| /// from file | |
| Gnuplot& plotfile_x(const std::string &filename, | |
| const unsigned int column = 1, | |
| const std::string &title = ""); | |
| /// from std::vector | |
| template<typename X> | |
| Gnuplot& plot_x(const X& x, const std::string &title = ""); | |
| /// plot x,y pairs: x y | |
| /// from file | |
| Gnuplot& plotfile_xy(const std::string &filename, | |
| const unsigned int column_x = 1, | |
| const unsigned int column_y = 2, | |
| const std::string &title = ""); | |
| /// from data | |
| template<typename X, typename Y> | |
| Gnuplot& plot_xy(const X& x, const Y& y, const std::string &title = ""); | |
| /// plot x,y pairs with dy errorbars: x y dy | |
| /// from file | |
| Gnuplot& plotfile_xy_err(const std::string &filename, | |
| const unsigned int column_x = 1, | |
| const unsigned int column_y = 2, | |
| const unsigned int column_dy = 3, | |
| const std::string &title = ""); | |
| /// from data | |
| template<typename X, typename Y, typename E> | |
| Gnuplot& plot_xy_err(const X &x, const Y &y, const E &dy, | |
| const std::string &title = ""); | |
| /// plot x,y,z triples: x y z | |
| /// from file | |
| Gnuplot& plotfile_xyz(const std::string &filename, | |
| const unsigned int column_x = 1, | |
| const unsigned int column_y = 2, | |
| const unsigned int column_z = 3, | |
| const std::string &title = ""); | |
| /// from std::vector | |
| template<typename X, typename Y, typename Z> | |
| Gnuplot& plot_xyz(const X &x, | |
| const Y &y, | |
| const Z &z, | |
| const std::string &title = ""); | |
| /// plot an equation of the form: y = ax + b, you supply a and b | |
| Gnuplot& plot_slope(const double a, | |
| const double b, | |
| const std::string &title = ""); | |
| /// plot an equation supplied as a std::string y=f(x), write only the function f(x) not y= | |
| /// the independent variable has to be x | |
| /// binary operators: ** exponentiation, * multiply, / divide, + add, - substract, % modulo | |
| /// unary operators: - minus, ! factorial | |
| /// elementary functions: rand(x), abs(x), sgn(x), ceil(x), floor(x), int(x), imag(x), real(x), arg(x), | |
| /// sqrt(x), exp(x), log(x), log10(x), sin(x), cos(x), tan(x), asin(x), acos(x), atan(x), atan2(y,x), | |
| /// sinh(x), cosh(x), tanh(x), asinh(x), acosh(x), atanh(x) | |
| /// special functions: erf(x), erfc(x), inverf(x), gamma(x), igamma(a,x), lgamma(x), ibeta(p,q,x), | |
| /// besj0(x), besj1(x), besy0(x), besy1(x), lambertw(x) | |
| /// statistical fuctions: norm(x), invnorm(x) | |
| Gnuplot& plot_equation(const std::string &equation, | |
| const std::string &title = ""); | |
| /// plot an equation supplied as a std::string z=f(x,y), write only the function f(x,y) not z= | |
| /// the independent variables have to be x and y | |
| Gnuplot& plot_equation3d(const std::string &equation, | |
| const std::string &title = ""); | |
| /// plot image | |
| Gnuplot& plot_image(const unsigned char *ucPicBuf, | |
| const unsigned int iWidth, | |
| const unsigned int iHeight, | |
| const std::string &title = ""); | |
| //---------------------------------------------------------------------------------- | |
| ///\brief replot repeats the last plot or splot command. | |
| /// this can be useful for viewing a plot with different set options, | |
| /// or when generating the same plot for several devices (showonscreen, savetops) | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return --- | |
| //---------------------------------------------------------------------------------- | |
| inline Gnuplot& replot(void){if (nplots > 0) cmd("replot");return *this;}; | |
| /// resets a gnuplot session (next plot will erase previous ones) | |
| Gnuplot& reset_plot(); | |
| /// resets a gnuplot session and sets all variables to default | |
| Gnuplot& reset_all(); | |
| /// deletes temporary files | |
| void remove_tmpfiles(); | |
| // ------------------------------------------------------------------- | |
| /// \brief Is the gnuplot session valid ?? | |
| /// | |
| /// | |
| /// \param --- | |
| /// | |
| /// \return true if valid, false if not | |
| // ------------------------------------------------------------------- | |
| inline bool is_valid(){return(valid);}; | |
| }; | |
| //------------------------------------------------------------------------------ | |
| // | |
| // initialize static data | |
| // | |
| int Gnuplot::tmpfile_num = 0; | |
| std::string Gnuplot::m_sGNUPlotFileName = "pgnuplot.exe"; | |
| std::string Gnuplot::m_sGNUPlotPath = "C:/program files/gnuplot/bin/"; | |
| std::string Gnuplot::terminal_std = "windows"; | |
| //------------------------------------------------------------------------------ | |
| // | |
| // constructor: set a style during construction | |
| // | |
| inline Gnuplot::Gnuplot(const std::string &style) | |
| :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) | |
| { | |
| init(); | |
| set_style(style); | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // constructor: open a new session, plot a signal (x) | |
| // | |
| inline Gnuplot::Gnuplot(const std::vector<double> &x, | |
| const std::string &title, | |
| const std::string &style, | |
| const std::string &labelx, | |
| const std::string &labely) | |
| :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) | |
| { | |
| init(); | |
| set_style(style); | |
| set_xlabel(labelx); | |
| set_ylabel(labely); | |
| plot_x(x,title); | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // constructor: open a new session, plot a signal (x,y) | |
| // | |
| inline Gnuplot::Gnuplot(const std::vector<double> &x, | |
| const std::vector<double> &y, | |
| const std::string &title, | |
| const std::string &style, | |
| const std::string &labelx, | |
| const std::string &labely) | |
| :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) | |
| { | |
| init(); | |
| set_style(style); | |
| set_xlabel(labelx); | |
| set_ylabel(labely); | |
| plot_xy(x,y,title); | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // constructor: open a new session, plot a signal (x,y,z) | |
| // | |
| inline Gnuplot::Gnuplot(const std::vector<double> &x, | |
| const std::vector<double> &y, | |
| const std::vector<double> &z, | |
| const std::string &title, | |
| const std::string &style, | |
| const std::string &labelx, | |
| const std::string &labely, | |
| const std::string &labelz) | |
| :gnucmd(NULL) ,valid(false) ,two_dim(false) ,nplots(0) | |
| { | |
| init(); | |
| set_style(style); | |
| set_xlabel(labelx); | |
| set_ylabel(labely); | |
| set_zlabel(labelz); | |
| plot_xyz(x,y,z,title); | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| /// Plots a 2d graph from a list of doubles: x | |
| // | |
| template<typename X> | |
| Gnuplot& Gnuplot::plot_x(const X& x, const std::string &title) | |
| { | |
| if (x.size() == 0) | |
| { | |
| throw GnuplotException("std::vector too small"); | |
| return *this; | |
| } | |
| std::ofstream tmp; | |
| std::string name = create_tmpfile(tmp); | |
| if (name == "") | |
| return *this; | |
| // | |
| // write the data to file | |
| // | |
| for (unsigned int i = 0; i < x.size(); i++) | |
| tmp << x[i] << std::endl; | |
| tmp.flush(); | |
| tmp.close(); | |
| plotfile_x(name, 1, title); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| /// Plots a 2d graph from a list of doubles: x y | |
| // | |
| template<typename X, typename Y> | |
| Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title) | |
| { | |
| if (x.size() == 0 || y.size() == 0) | |
| { | |
| throw GnuplotException("std::vectors too small"); | |
| return *this; | |
| } | |
| if (x.size() != y.size()) | |
| { | |
| throw GnuplotException("Length of the std::vectors differs"); | |
| return *this; | |
| } | |
| std::ofstream tmp; | |
| std::string name = create_tmpfile(tmp); | |
| if (name == "") | |
| return *this; | |
| // | |
| // write the data to file | |
| // | |
| for (unsigned int i = 0; i < x.size(); i++) | |
| tmp << x[i] << " " << y[i] << std::endl; | |
| tmp.flush(); | |
| tmp.close(); | |
| plotfile_xy(name, 1, 2, title); | |
| return *this; | |
| } | |
| ///----------------------------------------------------------------------------- | |
| /// | |
| /// plot x,y pairs with dy errorbars | |
| /// | |
| template<typename X, typename Y, typename E> | |
| Gnuplot& Gnuplot::plot_xy_err(const X &x, | |
| const Y &y, | |
| const E &dy, | |
| const std::string &title) | |
| { | |
| if (x.size() == 0 || y.size() == 0 || dy.size() == 0) | |
| { | |
| throw GnuplotException("std::vectors too small"); | |
| return *this; | |
| } | |
| if (x.size() != y.size() || y.size() != dy.size()) | |
| { | |
| throw GnuplotException("Length of the std::vectors differs"); | |
| return *this; | |
| } | |
| std::ofstream tmp; | |
| std::string name = create_tmpfile(tmp); | |
| if (name == "") | |
| return *this; | |
| // | |
| // write the data to file | |
| // | |
| for (unsigned int i = 0; i < x.size(); i++) | |
| tmp << x[i] << " " << y[i] << " " << dy[i] << std::endl; | |
| tmp.flush(); | |
| tmp.close(); | |
| // Do the actual plot | |
| plotfile_xy_err(name, 1, 2, 3, title); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Plots a 3d graph from a list of doubles: x y z | |
| // | |
| template<typename X, typename Y, typename Z> | |
| Gnuplot& Gnuplot::plot_xyz(const X &x, | |
| const Y &y, | |
| const Z &z, | |
| const std::string &title) | |
| { | |
| if (x.size() == 0 || y.size() == 0 || z.size() == 0) | |
| { | |
| throw GnuplotException("std::vectors too small"); | |
| return *this; | |
| } | |
| if (x.size() != y.size() || x.size() != z.size()) | |
| { | |
| throw GnuplotException("Length of the std::vectors differs"); | |
| return *this; | |
| } | |
| std::ofstream tmp; | |
| std::string name = create_tmpfile(tmp); | |
| if (name == "") | |
| return *this; | |
| // | |
| // write the data to file | |
| // | |
| for (unsigned int i = 0; i < x.size(); i++) | |
| tmp << x[i] << " " << y[i] << " " << z[i] <<std::endl; | |
| tmp.flush(); | |
| tmp.close(); | |
| plotfile_xyz(name, 1, 2, 3, title); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // define static member function: set Gnuplot path manual | |
| // for windows: path with slash '/' not backslash '\' | |
| // | |
| bool Gnuplot::set_GNUPlotPath(const std::string &path) | |
| { | |
| std::string tmp = path + "/" + Gnuplot::m_sGNUPlotFileName; | |
| if ( Gnuplot::file_exists(tmp,0) ) // check existence | |
| { | |
| Gnuplot::m_sGNUPlotPath = path; | |
| return true; | |
| } | |
| else | |
| { | |
| Gnuplot::m_sGNUPlotPath.clear(); | |
| return false; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // define static member function: set standart terminal, used by showonscreen | |
| // defaults: Windows - win, Linux - x11, Mac - aqua | |
| // | |
| void Gnuplot::set_terminal_std(const std::string &type) | |
| { | |
| #if defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) | |
| if (type.find("x11") != std::string::npos && getenv("DISPLAY") == NULL) | |
| { | |
| throw GnuplotException("Can't find DISPLAY variable"); | |
| } | |
| #endif | |
| Gnuplot::terminal_std = type; | |
| return; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // A string tokenizer taken from http://www.sunsite.ualberta.ca/Documentation/ | |
| // /Gnu/libstdc++-2.90.8/html/21_strings/stringtok_std_h.txt | |
| // | |
| template <typename Container> | |
| void stringtok (Container &container, | |
| std::string const &in, | |
| const char * const delimiters = " \t\n") | |
| { | |
| const std::string::size_type len = in.length(); | |
| std::string::size_type i = 0; | |
| while ( i < len ) | |
| { | |
| // eat leading whitespace | |
| i = in.find_first_not_of (delimiters, i); | |
| if (i == std::string::npos) | |
| return; // nothing left but white space | |
| // find the end of the token | |
| std::string::size_type j = in.find_first_of (delimiters, i); | |
| // push token | |
| if (j == std::string::npos) | |
| { | |
| container.push_back (in.substr(i)); | |
| return; | |
| } | |
| else | |
| container.push_back (in.substr(i, j-i)); | |
| // set up for next loop | |
| i = j + 1; | |
| } | |
| return; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Destructor: needed to delete temporary files | |
| // | |
| Gnuplot::~Gnuplot() | |
| { | |
| // remove_tmpfiles(); | |
| // A stream opened by popen() should be closed by pclose() | |
| #if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__) | |
| if (_pclose(gnucmd) == -1) | |
| #elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__) | |
| if (pclose(gnucmd) == -1) | |
| #endif | |
| throw GnuplotException("Problem closing communication to gnuplot"); | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Resets a gnuplot session (next plot will erase previous ones) | |
| // | |
| Gnuplot& Gnuplot::reset_plot() | |
| { | |
| // remove_tmpfiles(); | |
| nplots = 0; | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // resets a gnuplot session and sets all varibles to default | |
| // | |
| Gnuplot& Gnuplot::reset_all() | |
| { | |
| // remove_tmpfiles(); | |
| nplots = 0; | |
| cmd("reset"); | |
| cmd("clear"); | |
| pstyle = "points"; | |
| smooth = ""; | |
| showonscreen(); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Change the plotting style of a gnuplot session | |
| // | |
| Gnuplot& Gnuplot::set_style(const std::string &stylestr) | |
| { | |
| if (stylestr.find("lines") == std::string::npos && | |
| stylestr.find("points") == std::string::npos && | |
| stylestr.find("linespoints") == std::string::npos && | |
| stylestr.find("impulses") == std::string::npos && | |
| stylestr.find("dots") == std::string::npos && | |
| stylestr.find("steps") == std::string::npos && | |
| stylestr.find("fsteps") == std::string::npos && | |
| stylestr.find("histeps") == std::string::npos && | |
| stylestr.find("boxes") == std::string::npos && // 1-4 columns of data are required | |
| stylestr.find("filledcurves") == std::string::npos && | |
| stylestr.find("histograms") == std::string::npos ) //only for one data column | |
| // stylestr.find("labels") == std::string::npos && // 3 columns of data are required | |
| // stylestr.find("xerrorbars") == std::string::npos && // 3-4 columns of data are required | |
| // stylestr.find("xerrorlines") == std::string::npos && // 3-4 columns of data are required | |
| // stylestr.find("errorbars") == std::string::npos && // 3-4 columns of data are required | |
| // stylestr.find("errorlines") == std::string::npos && // 3-4 columns of data are required | |
| // stylestr.find("yerrorbars") == std::string::npos && // 3-4 columns of data are required | |
| // stylestr.find("yerrorlines") == std::string::npos && // 3-4 columns of data are required | |
| // stylestr.find("boxerrorbars") == std::string::npos && // 3-5 columns of data are required | |
| // stylestr.find("xyerrorbars") == std::string::npos && // 4,6,7 columns of data are required | |
| // stylestr.find("xyerrorlines") == std::string::npos && // 4,6,7 columns of data are required | |
| // stylestr.find("boxxyerrorbars") == std::string::npos && // 4,6,7 columns of data are required | |
| // stylestr.find("financebars") == std::string::npos && // 5 columns of data are required | |
| // stylestr.find("candlesticks") == std::string::npos && // 5 columns of data are required | |
| // stylestr.find("vectors") == std::string::npos && | |
| // stylestr.find("image") == std::string::npos && | |
| // stylestr.find("rgbimage") == std::string::npos && | |
| // stylestr.find("pm3d") == std::string::npos ) | |
| { | |
| pstyle = std::string("points"); | |
| } | |
| else | |
| { | |
| pstyle = stylestr; | |
| } | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // smooth: interpolation and approximation of data | |
| // | |
| Gnuplot& Gnuplot::set_smooth(const std::string &stylestr) | |
| { | |
| if (stylestr.find("unique") == std::string::npos && | |
| stylestr.find("frequency") == std::string::npos && | |
| stylestr.find("csplines") == std::string::npos && | |
| stylestr.find("acsplines") == std::string::npos && | |
| stylestr.find("bezier") == std::string::npos && | |
| stylestr.find("sbezier") == std::string::npos ) | |
| { | |
| smooth = ""; | |
| } | |
| else | |
| { | |
| smooth = stylestr; | |
| } | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // sets terminal type to windows / x11 | |
| // | |
| Gnuplot& Gnuplot::showonscreen() | |
| { | |
| cmd("set output"); | |
| cmd("set terminal " + Gnuplot::terminal_std); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // saves a gnuplot session to a postscript file | |
| // | |
| Gnuplot& Gnuplot::savetops(const std::string &filename) | |
| { | |
| cmd("set terminal postscript color"); | |
| std::ostringstream cmdstr; | |
| cmdstr << "set output \"" << filename << ".ps\""; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Switches legend on | |
| // | |
| Gnuplot& Gnuplot::set_legend(const std::string &position) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set key " << position; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // turns on log scaling for the x axis | |
| // | |
| Gnuplot& Gnuplot::set_xlogscale(const double base) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set logscale x " << base; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // turns on log scaling for the y axis | |
| // | |
| Gnuplot& Gnuplot::set_ylogscale(const double base) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set logscale y " << base; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // turns on log scaling for the z axis | |
| // | |
| Gnuplot& Gnuplot::set_zlogscale(const double base) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set logscale z " << base; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // scales the size of the points used in plots | |
| // | |
| Gnuplot& Gnuplot::set_pointsize(const double pointsize) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set pointsize " << pointsize; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // set isoline density (grid) for plotting functions as surfaces | |
| // | |
| Gnuplot& Gnuplot::set_samples(const int samples) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set samples " << samples; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // set isoline density (grid) for plotting functions as surfaces | |
| // | |
| Gnuplot& Gnuplot::set_isosamples(const int isolines) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set isosamples " << isolines; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // enables contour drawing for surfaces set contour {base | surface | both} | |
| // | |
| Gnuplot& Gnuplot::set_contour(const std::string &position) | |
| { | |
| if (position.find("base") == std::string::npos && | |
| position.find("surface") == std::string::npos && | |
| position.find("both") == std::string::npos ) | |
| { | |
| cmd("set contour base"); | |
| } | |
| else | |
| { | |
| cmd("set contour " + position); | |
| } | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // set labels | |
| // | |
| // set the xlabel | |
| Gnuplot& Gnuplot::set_xlabel(const std::string &label) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set xlabel \"" << label << "\""; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // set the ylabel | |
| // | |
| Gnuplot& Gnuplot::set_ylabel(const std::string &label) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set ylabel \"" << label << "\""; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // set the zlabel | |
| // | |
| Gnuplot& Gnuplot::set_zlabel(const std::string &label) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set zlabel \"" << label << "\""; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // set range | |
| // | |
| // set the xrange | |
| Gnuplot& Gnuplot::set_xrange(const double iFrom, | |
| const double iTo) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set xrange[" << iFrom << ":" << iTo << "]"; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // set the yrange | |
| // | |
| Gnuplot& Gnuplot::set_yrange(const double iFrom, | |
| const double iTo) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set yrange[" << iFrom << ":" << iTo << "]"; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // set the zrange | |
| // | |
| Gnuplot& Gnuplot::set_zrange(const double iFrom, | |
| const double iTo) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set zrange[" << iFrom << ":" << iTo << "]"; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // set the palette range | |
| // | |
| Gnuplot& Gnuplot::set_cbrange(const double iFrom, | |
| const double iTo) | |
| { | |
| std::ostringstream cmdstr; | |
| cmdstr << "set cbrange[" << iFrom << ":" << iTo << "]"; | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Plots a linear equation y=ax+b (where you supply the | |
| // slope a and intercept b) | |
| // | |
| Gnuplot& Gnuplot::plot_slope(const double a, | |
| const double b, | |
| const std::string &title) | |
| { | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == true) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "plot "; | |
| cmdstr << a << " * x + " << b << " title \""; | |
| if (title == "") | |
| cmdstr << "f(x) = " << a << " * x + " << b; | |
| else | |
| cmdstr << title; | |
| cmdstr << "\" with " << pstyle; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Plot an equation supplied as a std::string y=f(x) (only f(x) expected) | |
| // | |
| Gnuplot& Gnuplot::plot_equation(const std::string &equation, | |
| const std::string &title) | |
| { | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == true) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "plot "; | |
| cmdstr << equation << " title \""; | |
| if (title == "") | |
| cmdstr << "f(x) = " << equation; | |
| else | |
| cmdstr << title; | |
| cmdstr << "\" with " << pstyle; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // plot an equation supplied as a std::string y=(x) | |
| // | |
| Gnuplot& Gnuplot::plot_equation3d(const std::string &equation, | |
| const std::string &title) | |
| { | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == false) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "splot "; | |
| cmdstr << equation << " title \""; | |
| if (title == "") | |
| cmdstr << "f(x,y) = " << equation; | |
| else | |
| cmdstr << title; | |
| cmdstr << "\" with " << pstyle; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Plots a 2d graph from a list of doubles (x) saved in a file | |
| // | |
| Gnuplot& Gnuplot::plotfile_x(const std::string &filename, | |
| const unsigned int column, | |
| const std::string &title) | |
| { | |
| // | |
| // check if file exists | |
| // | |
| file_available(filename); | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == true) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "plot "; | |
| cmdstr << "\"" << filename << "\" using " << column; | |
| if (title == "") | |
| cmdstr << " notitle "; | |
| else | |
| cmdstr << " title \"" << title << "\" "; | |
| if(smooth == "") | |
| cmdstr << "with " << pstyle; | |
| else | |
| cmdstr << "smooth " << smooth; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); //nplots++; two_dim = true; already in cmd(); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Plots a 2d graph from a list of doubles (x y) saved in a file | |
| // | |
| Gnuplot& Gnuplot::plotfile_xy(const std::string &filename, | |
| const unsigned int column_x, | |
| const unsigned int column_y, | |
| const std::string &title) | |
| { | |
| // | |
| // check if file exists | |
| // | |
| file_available(filename); | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == true) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "plot "; | |
| cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y; | |
| if (title == "") | |
| cmdstr << " notitle "; | |
| else | |
| cmdstr << " title \"" << title << "\" "; | |
| if(smooth == "") | |
| cmdstr << "with " << pstyle; | |
| else | |
| cmdstr << "smooth " << smooth; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Plots a 2d graph with errorbars from a list of doubles (x y dy) in a file | |
| // | |
| Gnuplot& Gnuplot::plotfile_xy_err(const std::string &filename, | |
| const unsigned int column_x, | |
| const unsigned int column_y, | |
| const unsigned int column_dy, | |
| const std::string &title) | |
| { | |
| // | |
| // check if file exists | |
| // | |
| file_available(filename); | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == true) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "plot "; | |
| cmdstr << "\"" << filename << "\" using " | |
| << column_x << ":" << column_y << ":" << column_dy | |
| << " with errorbars "; | |
| if (title == "") | |
| cmdstr << " notitle "; | |
| else | |
| cmdstr << " title \"" << title << "\" "; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Plots a 3d graph from a list of doubles (x y z) saved in a file | |
| // | |
| Gnuplot& Gnuplot::plotfile_xyz(const std::string &filename, | |
| const unsigned int column_x, | |
| const unsigned int column_y, | |
| const unsigned int column_z, | |
| const std::string &title) | |
| { | |
| // | |
| // check if file exists | |
| // | |
| file_available(filename); | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == false) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "splot "; | |
| cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y | |
| << ":" << column_z; | |
| if (title == "") | |
| cmdstr << " notitle with " << pstyle; | |
| else | |
| cmdstr << " title \"" << title << "\" with " << pstyle; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| /// * note that this function is not valid for versions of GNUPlot below 4.2 | |
| // | |
| Gnuplot& Gnuplot::plot_image(const unsigned char * ucPicBuf, | |
| const unsigned int iWidth, | |
| const unsigned int iHeight, | |
| const std::string &title) | |
| { | |
| std::ofstream tmp; | |
| std::string name = create_tmpfile(tmp); | |
| if (name == "") | |
| return *this; | |
| // | |
| // write the data to file | |
| // | |
| int iIndex = 0; | |
| for(int iRow = 0; iRow < iHeight; iRow++) | |
| { | |
| for(int iColumn = 0; iColumn < iWidth; iColumn++) | |
| { | |
| tmp << iColumn << " " << iRow << " " | |
| << static_cast<float>(ucPicBuf[iIndex++]) << std::endl; | |
| } | |
| } | |
| tmp.flush(); | |
| tmp.close(); | |
| std::ostringstream cmdstr; | |
| // | |
| // command to be sent to gnuplot | |
| // | |
| if (nplots > 0 && two_dim == true) | |
| cmdstr << "replot "; | |
| else | |
| cmdstr << "plot "; | |
| if (title == "") | |
| cmdstr << "\"" << name << "\" with image"; | |
| else | |
| cmdstr << "\"" << name << "\" title \"" << title << "\" with image"; | |
| // | |
| // Do the actual plot | |
| // | |
| cmd(cmdstr.str()); | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Sends a command to an active gnuplot session | |
| // | |
| Gnuplot& Gnuplot::cmd(const std::string &cmdstr) | |
| { | |
| if( !(valid) ) | |
| { | |
| return *this; | |
| } | |
| // int fputs ( const char * str, FILE * stream ); | |
| // writes the string str to the stream. | |
| // The function begins copying from the address specified (str) until it | |
| // reaches the terminating null character ('\0'). This final | |
| // null-character is not copied to the stream. | |
| fputs( (cmdstr+"\n").c_str(), gnucmd ); | |
| // int fflush ( FILE * stream ); | |
| // If the given stream was open for writing and the last i/o operation was | |
| // an output operation, any unwritten data in the output buffer is written | |
| // to the file. If the argument is a null pointer, all open files are | |
| // flushed. The stream remains open after this call. | |
| fflush(gnucmd); | |
| if( cmdstr.find("replot") != std::string::npos ) | |
| { | |
| return *this; | |
| } | |
| else if( cmdstr.find("splot") != std::string::npos ) | |
| { | |
| two_dim = false; | |
| nplots++; | |
| } | |
| else if( cmdstr.find("plot") != std::string::npos ) | |
| { | |
| two_dim = true; | |
| nplots++; | |
| } | |
| return *this; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Opens up a gnuplot session, ready to receive commands | |
| // | |
| void Gnuplot::init() | |
| { | |
| // char * getenv ( const char * name ); get value of environment variable | |
| // Retrieves a C string containing the value of the environment variable | |
| // whose name is specified as argument. If the requested variable is not | |
| // part of the environment list, the function returns a NULL pointer. | |
| // if gnuplot not available | |
| // | |
| // open pipe | |
| // | |
| // FILE *popen(const char *command, const char *mode); | |
| // The popen() function shall execute the command specified by the string | |
| // command, create a pipe between the calling program and the executed | |
| // command, and return a pointer to a stream that can be used to either read | |
| // from or write to the pipe. | |
| gnucmd = _popen("gnuplot","w"); | |
| // popen() shall return a pointer to an open stream that can be used to read | |
| // or write to the pipe. Otherwise, it shall return a null pointer and may | |
| // set errno to indicate the error. | |
| if (!gnucmd) | |
| { | |
| valid = false; | |
| throw GnuplotException("Couldn't open connection to gnuplot"); | |
| } | |
| nplots = 0; | |
| valid = true; | |
| smooth = ""; | |
| //set terminal type | |
| showonscreen(); | |
| return; | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Find out if a command lives in m_sGNUPlotPath or in PATH | |
| // | |
| bool Gnuplot::get_program_path() | |
| { | |
| // | |
| // first look in m_sGNUPlotPath for Gnuplot | |
| // | |
| std::string tmp = Gnuplot::m_sGNUPlotPath + "/" + | |
| Gnuplot::m_sGNUPlotFileName; | |
| if ( Gnuplot::file_exists(tmp,0) ) // check existence | |
| { | |
| return true; | |
| } | |
| // | |
| // second look in PATH for Gnuplot | |
| // | |
| char *path; | |
| // Retrieves a C string containing the value of environment variable PATH | |
| path = getenv("PATH"); | |
| if (path == NULL) | |
| { | |
| throw GnuplotException("Path is not set"); | |
| return false; | |
| } | |
| else | |
| { | |
| std::list<std::string> ls; | |
| //split path (one long string) into list ls of strings | |
| stringtok(ls,path,";"); | |
| // scan list for Gnuplot program files | |
| for (std::list<std::string>::const_iterator i = ls.begin(); | |
| i != ls.end(); ++i) | |
| { | |
| tmp = (*i) + "/" + Gnuplot::m_sGNUPlotFileName; | |
| if ( Gnuplot::file_exists(tmp,0) ) // check existence | |
| { | |
| Gnuplot::m_sGNUPlotPath = *i; // set m_sGNUPlotPath | |
| return true; | |
| } | |
| } | |
| tmp = "Can't find gnuplot neither in PATH nor in \"" + | |
| Gnuplot::m_sGNUPlotPath + "\""; | |
| throw GnuplotException(tmp); | |
| Gnuplot::m_sGNUPlotPath = ""; | |
| return false; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // check if file exists | |
| // | |
| bool Gnuplot::file_exists(const std::string &filename, int mode) | |
| { | |
| if ( mode < 0 || mode > 7) | |
| { | |
| throw std::runtime_error("In function \"Gnuplot::file_exists\": mode\ | |
| has to be an integer between 0 and 7"); | |
| return false; | |
| } | |
| // int _access(const char *path, int mode); | |
| // returns 0 if the file has the given mode, | |
| // it returns -1 if the named file does not exist or is not accessible in | |
| // the given mode | |
| // mode = 0 (F_OK) (default): checks file for existence only | |
| // mode = 1 (X_OK): execution permission | |
| // mode = 2 (W_OK): write permission | |
| // mode = 4 (R_OK): read permission | |
| // mode = 6 : read and write permission | |
| // mode = 7 : read, write and execution permission | |
| if (_access(filename.c_str(), mode) == 0) | |
| { | |
| return true; | |
| } | |
| else | |
| { | |
| return false; | |
| } | |
| } | |
| bool Gnuplot::file_available(const std::string &filename){ | |
| std::ostringstream except; | |
| if( Gnuplot::file_exists(filename,0) ) // check existence | |
| { | |
| if( !(Gnuplot::file_exists(filename,4)) ){// check read permission | |
| except << "No read permission for File \"" << filename << "\""; | |
| throw GnuplotException( except.str() ); | |
| return false; | |
| } | |
| } | |
| else{ | |
| except << "File \"" << filename << "\" does not exist"; | |
| throw GnuplotException( except.str() ); | |
| return false; | |
| } | |
| } | |
| //------------------------------------------------------------------------------ | |
| // | |
| // Opens a temporary file | |
| // | |
| std::string Gnuplot::create_tmpfile(std::ofstream &tmp) | |
| { | |
| char name[] = "gnuplotiXXXXXX"; //tmp file in working directory | |
| // | |
| // check if maximum number of temporary files reached | |
| // | |
| if (Gnuplot::tmpfile_num == GP_MAX_TMP_FILES - 1) | |
| { | |
| std::ostringstream except; | |
| except << "Maximum number of temporary files reached (" | |
| << GP_MAX_TMP_FILES << "): cannot open more files" << std::endl; | |
| throw GnuplotException( except.str() ); | |
| return ""; | |
| } | |
| // int mkstemp(char *name); | |
| // shall replace the contents of the string pointed to by "name" by a unique | |
| // filename, and return a file descriptor for the file open for reading and | |
| // writing. Otherwise, -1 shall be returned if no suitable file could be | |
| // created. The string in template should look like a filename with six | |
| // trailing 'X' s; mkstemp() replaces each 'X' with a character from the | |
| // portable filename character set. The characters are chosen such that the | |
| // resulting name does not duplicate the name of an existing file at the | |
| // time of a call to mkstemp() | |
| // | |
| // open temporary files for output | |
| // | |
| if (_mktemp(name) == NULL) | |
| { | |
| std::ostringstream except; | |
| except << "Cannot create temporary file \"" << name << "\""; | |
| throw GnuplotException(except.str()); | |
| return ""; | |
| } | |
| tmp.open(name); | |
| if (tmp.bad()) | |
| { | |
| std::ostringstream except; | |
| except << "Cannot create temporary file \"" << name << "\""; | |
| throw GnuplotException(except.str()); | |
| return ""; | |
| } | |
| // | |
| // Save the temporary filename | |
| // | |
| tmpfile_list.push_back(name); | |
| Gnuplot::tmpfile_num++; | |
| return name; | |
| } | |
| void Gnuplot::remove_tmpfiles(){ | |
| if ((tmpfile_list).size() > 0) | |
| { | |
| for (unsigned int i = 0; i < tmpfile_list.size(); i++) | |
| remove( tmpfile_list[i].c_str() ); | |
| Gnuplot::tmpfile_num -= tmpfile_list.size(); | |
| } | |
| } | |
| #endif |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment