2017-10-21 11:05:51 +00:00
|
|
|
/*!
|
|
|
|
* \file gnuplot_i.h
|
|
|
|
* \brief A C++ interface to gnuplot.
|
|
|
|
* \author Carles Fernandez-Prades, 2017. cfernandez(at)cttc.es
|
|
|
|
*
|
2017-10-22 07:14:25 +00:00
|
|
|
* Original source code found at https://code.google.com/archive/p/gnuplot-cpp/
|
2017-10-21 11:05:51 +00:00
|
|
|
* by Jeremy Conlin jeremit0(at)gmail.com
|
|
|
|
*
|
|
|
|
* 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)
|
2017-10-22 07:14:25 +00:00
|
|
|
* 4. Some fixes and improvements for Linux and macOS
|
|
|
|
* by C. Fernandez (22/10/17)
|
2017-10-21 11:05:51 +00:00
|
|
|
* -------------------------------------------------------------------------
|
|
|
|
*
|
|
|
|
* Copyright (C) 2013-2017 (see AUTHORS file for a list of contributors)
|
|
|
|
*
|
|
|
|
* GNSS-SDR is a software defined Global Navigation
|
|
|
|
* Satellite Systems receiver
|
|
|
|
*
|
|
|
|
* This file is part of GNSS-SDR.
|
|
|
|
*
|
|
|
|
* GNSS-SDR is free software: you can redistribute it and/or modify
|
|
|
|
* it under the terms of the GNU General Public License as published by
|
|
|
|
* the Free Software Foundation, either version 3 of the License, or
|
|
|
|
* (at your option) any later version.
|
|
|
|
*
|
|
|
|
* GNSS-SDR is distributed in the hope that it will be useful,
|
|
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
* GNU General Public License for more details.
|
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU General Public License
|
|
|
|
* along with GNSS-SDR. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
*
|
|
|
|
* -------------------------------------------------------------------------
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
|
|
#ifndef GNSS_SDR_GNUPLOT_I_H_
|
|
|
|
#define GNSS_SDR_GNUPLOT_I_H_
|
|
|
|
|
|
|
|
|
|
|
|
#include <iostream>
|
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
2017-10-24 12:23:59 +00:00
|
|
|
#include <fstream>
|
2017-10-21 11:05:51 +00:00
|
|
|
#include <sstream> // for std::ostringstream
|
2017-10-24 12:23:59 +00:00
|
|
|
#include <stdexcept>
|
|
|
|
#include <cstdio>
|
2017-10-21 11:05:51 +00:00
|
|
|
#include <cstdlib> // for getenv()
|
|
|
|
#include <list> // for std::list
|
|
|
|
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
2017-10-21 11:05:51 +00:00
|
|
|
//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
|
2017-10-24 12:23:59 +00:00
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
2017-10-21 11:05:51 +00:00
|
|
|
//all UNIX-like OSs (Linux, *BSD, MacOSX, Solaris, ...)
|
|
|
|
#include <unistd.h> // for access(), mkstemp()
|
|
|
|
#define GP_MAX_TMP_FILES 64
|
|
|
|
#else
|
|
|
|
#error unsupported or unknown operating system
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//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
|
|
|
|
// ---------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
void init();
|
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
// ---------------------------------------------------
|
|
|
|
///\brief creates tmpfile and returns its name
|
|
|
|
///
|
|
|
|
/// \param tmp --> points to the tempfile
|
|
|
|
///
|
|
|
|
/// \return <-- the name of the tempfile
|
|
|
|
// ---------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
std::string create_tmpfile(std::ofstream &tmp);
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
///\brief gnuplot path found?
|
|
|
|
///
|
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- found the gnuplot path (yes == true, no == false)
|
|
|
|
// ---------------------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
static bool get_program_path();
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------------
|
|
|
|
///\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)
|
|
|
|
// ---------------------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
static bool file_exists(const std::string &filename, int mode=0);
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
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
|
|
|
|
// ---------------------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& operator<<(const std::string &cmdstr)
|
|
|
|
{
|
2017-10-21 11:05:51 +00:00
|
|
|
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");
|
|
|
|
|
2017-10-22 20:33:27 +00:00
|
|
|
/// saves a gnuplot session to a pdf file, filename without extension
|
2017-10-22 21:04:39 +00:00
|
|
|
Gnuplot& savetopdf(const std::string &filename = "gnuplot_output", unsigned int font_size = 12);
|
2017-10-22 20:33:27 +00:00
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
// 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
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \return <-- a reference to a gnuplot object
|
|
|
|
// ----------------------------------------------------------------------
|
2017-10-24 12:23:59 +00:00
|
|
|
inline Gnuplot& unset_smooth(){ smooth = ""; return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// scales the size of the points used in plots
|
|
|
|
Gnuplot& set_pointsize(const double pointsize = 1.0);
|
|
|
|
|
|
|
|
/// turns grid on/off
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& set_grid() {cmd("set grid"); return *this;};
|
2017-10-24 12:23:59 +00:00
|
|
|
/// grid is not set by default
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& unset_grid(){cmd("unset grid"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// -----------------------------------------------
|
|
|
|
/// set the mulitplot mode
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// -----------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& set_multiplot(){cmd("set multiplot") ; return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// -----------------------------------------------
|
|
|
|
/// unsets the mulitplot mode
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// -----------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& unset_multiplot(){cmd("unset multiplot"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// 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
|
|
|
|
// --------------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
Gnuplot& set_hidden3d(){cmd("set hidden3d"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// ---------------------------------------------------------------------------
|
|
|
|
/// hidden3d is not set by default
|
|
|
|
///
|
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// ---------------------------------------------------------------------------
|
2017-10-24 12:23:59 +00:00
|
|
|
inline Gnuplot& unset_hidden3d(){cmd("unset hidden3d"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// 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
|
|
|
|
// ------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& unset_contour(){cmd("unset contour"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------
|
|
|
|
/// enables/disables the display of surfaces (for 3d plot)
|
|
|
|
///
|
2017-10-24 12:23:59 +00:00
|
|
|
/// \param ---
|
2017-10-21 11:05:51 +00:00
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// ------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& set_surface(){cmd("set surface"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// ----------------------------------------------------------
|
|
|
|
/// surface is set by default,
|
|
|
|
/// it disables the display of surfaces (for 3d plot)
|
|
|
|
///
|
2017-10-24 12:23:59 +00:00
|
|
|
/// \param ---
|
2017-10-21 11:05:51 +00:00
|
|
|
///
|
|
|
|
/// \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
|
2017-10-24 12:23:59 +00:00
|
|
|
Gnuplot& set_legend(const std::string &position = "default");
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
/// \brief Switches legend off
|
|
|
|
/// attention:legend is set by default
|
|
|
|
///
|
2017-10-24 12:23:59 +00:00
|
|
|
/// \param ---
|
2017-10-21 11:05:51 +00:00
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// ------------------------------------------------------------------
|
|
|
|
inline Gnuplot& unset_legend(){cmd("unset key"); return *this;}
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \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
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
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
|
|
|
|
// ---------------------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& unset_title(){this->set_title(); return *this;}
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// 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
|
2017-10-22 07:14:25 +00:00
|
|
|
Gnuplot& set_xrange(const double iFrom, const double iTo);
|
2017-10-21 11:05:51 +00:00
|
|
|
/// set y-axis - ranges
|
2017-10-22 07:14:25 +00:00
|
|
|
Gnuplot& set_yrange(const double iFrom, const double iTo);
|
2017-10-21 11:05:51 +00:00
|
|
|
/// set z-axis - ranges
|
2017-10-22 07:14:25 +00:00
|
|
|
Gnuplot& set_zrange(const double iFrom, const double iTo);
|
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
/// autoscale axis (set by default) of xaxis
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// -----------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& set_xautoscale(){cmd("set xrange restore"); cmd("set autoscale x"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// -----------------------------------------------
|
|
|
|
/// autoscale axis (set by default) of yaxis
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// -----------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& set_yautoscale(){cmd("set yrange restore"); cmd("set autoscale y"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
// -----------------------------------------------
|
|
|
|
/// autoscale axis (set by default) of zaxis
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
|
|
|
// -----------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& set_zautoscale(){cmd("set zrange restore"); cmd("set autoscale z"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// 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);
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
/// turns off log scaling for the x axis
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
inline Gnuplot& unset_xlogscale(){cmd("unset logscale x"); return *this;};
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
/// turns off log scaling for the y axis
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
inline Gnuplot& unset_ylogscale(){cmd("unset logscale y"); return *this;};
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
/// turns off log scaling for the z axis
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return <-- reference to the gnuplot object
|
2017-10-24 12:23:59 +00:00
|
|
|
// -----------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
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,
|
2017-10-24 12:23:59 +00:00
|
|
|
const std::string &title = "",
|
|
|
|
const unsigned int decimate = 1);
|
2017-10-21 11:05:51 +00:00
|
|
|
/// from data
|
|
|
|
template<typename X, typename Y>
|
2017-10-24 12:23:59 +00:00
|
|
|
Gnuplot& plot_xy(const X& x, const Y& y,
|
|
|
|
const std::string &title = "",
|
|
|
|
const unsigned int decimate = 1);
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// 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 = "");
|
|
|
|
|
2017-10-28 16:15:59 +00:00
|
|
|
template<typename X, typename Y, typename E>
|
|
|
|
Gnuplot& plot_grid3d(const X &x, const Y &y, const E &mag,
|
|
|
|
const std::string &title = "");
|
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
/// 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)
|
2017-10-22 07:14:25 +00:00
|
|
|
Gnuplot& plot_equation(const std::string &equation, const std::string &title = "");
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// 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
|
2017-10-22 07:14:25 +00:00
|
|
|
Gnuplot& plot_equation3d(const std::string &equation, const std::string &title = "");
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// plot image
|
|
|
|
Gnuplot& plot_image(const unsigned char *ucPicBuf,
|
|
|
|
const unsigned int iWidth,
|
|
|
|
const unsigned int iHeight,
|
|
|
|
const std::string &title = "");
|
|
|
|
|
2017-10-22 16:05:02 +00:00
|
|
|
/// plot circle
|
|
|
|
Gnuplot& plot_circle(double east, double north, double radius, const std::string &label = "");
|
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
//----------------------------------------------------------------------------------
|
|
|
|
///\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)
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \param ---
|
|
|
|
///
|
|
|
|
/// \return ---
|
|
|
|
//----------------------------------------------------------------------------------
|
2017-10-22 07:14:25 +00:00
|
|
|
inline Gnuplot& replot(void){if (nplots > 0) cmd("replot"); return *this;};
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
/// 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 ??
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
///
|
|
|
|
/// \param ---
|
2017-10-24 12:23:59 +00:00
|
|
|
///
|
2017-10-21 11:05:51 +00:00
|
|
|
/// \return true if valid, false if not
|
2017-10-24 12:23:59 +00:00
|
|
|
// -------------------------------------------------------------------
|
2017-10-21 11:05:51 +00:00
|
|
|
inline bool is_valid(){return(valid);};
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// initialize static data
|
|
|
|
//
|
|
|
|
int Gnuplot::tmpfile_num = 0;
|
|
|
|
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
std::string Gnuplot::m_sGNUPlotFileName = "pgnuplot.exe";
|
|
|
|
std::string Gnuplot::m_sGNUPlotPath = "C:/program files/gnuplot/bin/";
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
std::string Gnuplot::m_sGNUPlotFileName = "gnuplot";
|
|
|
|
std::string Gnuplot::m_sGNUPlotPath = "/usr/local/bin/";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
std::string Gnuplot::terminal_std = "windows";
|
|
|
|
#elif ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__)
|
|
|
|
std::string Gnuplot::terminal_std = "x11";
|
|
|
|
#elif defined(__APPLE__)
|
|
|
|
std::string Gnuplot::terminal_std = "aqua";
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// constructor: set a style during construction
|
|
|
|
//
|
|
|
|
inline Gnuplot::Gnuplot(const std::string &style)
|
2017-10-22 07:14:25 +00:00
|
|
|
:gnucmd(NULL), valid(false), two_dim(false), nplots(0)
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
{
|
|
|
|
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)
|
2017-10-22 07:14:25 +00:00
|
|
|
:gnucmd(NULL), valid(false), two_dim(false), nplots(0)
|
2017-10-21 11:05:51 +00:00
|
|
|
{
|
|
|
|
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)
|
2017-10-22 07:14:25 +00:00
|
|
|
:gnucmd(NULL), valid(false), two_dim(false), nplots(0)
|
2017-10-21 11:05:51 +00:00
|
|
|
{
|
|
|
|
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)
|
2017-10-22 07:14:25 +00:00
|
|
|
:gnucmd(NULL), valid(false), two_dim(false), nplots(0)
|
2017-10-21 11:05:51 +00:00
|
|
|
{
|
|
|
|
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>
|
2017-10-24 12:23:59 +00:00
|
|
|
Gnuplot& Gnuplot::plot_xy(const X& x, const Y& y, const std::string &title, const unsigned int decimate)
|
2017-10-21 11:05:51 +00:00
|
|
|
{
|
|
|
|
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();
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
plotfile_xy(name, 1, 2, title, decimate);
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-28 16:15:59 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Plots a 3d grid
|
|
|
|
//
|
|
|
|
template<typename X, typename Y, typename E>
|
|
|
|
Gnuplot& Gnuplot::plot_grid3d(const X &x,
|
|
|
|
const Y &y,
|
|
|
|
const E &mag,
|
|
|
|
const std::string &title)
|
|
|
|
{
|
|
|
|
if (x.size() == 0 || y.size() == 0 )
|
|
|
|
{
|
|
|
|
throw GnuplotException("std::vectors 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++)
|
|
|
|
{
|
|
|
|
for (unsigned int k = 0; k < y.size(); k++)
|
|
|
|
{
|
|
|
|
tmp << static_cast<float>(x.at(i)) << " " << static_cast<float>(y.at(k)) << " " << mag.at(i).at(k) << std::endl;
|
|
|
|
}
|
|
|
|
tmp.flush();
|
|
|
|
}
|
|
|
|
|
|
|
|
tmp.close();
|
|
|
|
|
|
|
|
std::ostringstream cmdstr;
|
|
|
|
cmdstr << "set ticslevel 0\n";
|
|
|
|
cmdstr << "set hidden3d\n";
|
|
|
|
cmdstr << "unset colorbox\n";
|
|
|
|
cmdstr << "set border 5\n";
|
|
|
|
cmdstr << "unset ztics\n";
|
|
|
|
|
|
|
|
cmdstr << " splot \"" << name << "\" u 1:2:3";
|
|
|
|
|
|
|
|
if (title == "")
|
|
|
|
cmdstr << " notitle with " << pstyle << " palette";
|
|
|
|
else
|
|
|
|
cmdstr << " title \"" << title << "\" with " << pstyle << " palette";
|
|
|
|
cmdstr << "\n";
|
|
|
|
|
|
|
|
//
|
|
|
|
// Do the actual plot
|
|
|
|
//
|
|
|
|
cmd(cmdstr.str());
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// 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 defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
if ( Gnuplot::file_exists(tmp,0) ) // check existence
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
if ( Gnuplot::file_exists(tmp,1) ) // check existence and execution permission
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
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
|
2017-10-22 16:05:02 +00:00
|
|
|
// throw GnuplotException("Problem closing communication to gnuplot");
|
|
|
|
std::cout << "Gnuplot window left open." << std::endl;
|
2017-10-21 11:05:51 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// 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()
|
|
|
|
{
|
2017-10-22 06:28:59 +00:00
|
|
|
std::string persist(" persist");
|
|
|
|
#ifdef __APPLE__
|
|
|
|
persist = "";
|
|
|
|
#endif
|
2017-10-21 11:05:51 +00:00
|
|
|
cmd("set output");
|
2017-10-22 06:28:59 +00:00
|
|
|
cmd("set terminal " + Gnuplot::terminal_std + persist);
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-22 20:33:27 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// saves a gnuplot session to a pdf file
|
|
|
|
//
|
2017-10-22 21:04:39 +00:00
|
|
|
Gnuplot& Gnuplot::savetopdf(const std::string &filename, unsigned int font_size)
|
2017-10-22 20:33:27 +00:00
|
|
|
{
|
|
|
|
std::ostringstream cmdstr;
|
2017-10-22 21:04:39 +00:00
|
|
|
cmdstr << "set term pdfcairo enhanced color font \"Times-New-Roman," + std::to_string(font_size) + "\"\n";
|
2017-10-22 20:33:27 +00:00
|
|
|
cmdstr << "set output \"" << filename << ".pdf\"\n";
|
|
|
|
cmdstr << "replot";
|
|
|
|
cmd(cmdstr.str());
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// saves a gnuplot session to a postscript file
|
|
|
|
//
|
|
|
|
Gnuplot& Gnuplot::savetops(const std::string &filename)
|
|
|
|
{
|
|
|
|
std::ostringstream cmdstr;
|
2017-10-22 06:20:51 +00:00
|
|
|
cmdstr << "set term postscript landscape enhanced color dashed \"Times-Roman\" 18\n";
|
2017-10-21 14:33:26 +00:00
|
|
|
cmdstr << "set output \"" << filename << ".ps\"\n";
|
|
|
|
cmdstr << "replot";
|
2017-10-21 11:05:51 +00:00
|
|
|
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,
|
2017-10-24 12:23:59 +00:00
|
|
|
const std::string &title,
|
|
|
|
const unsigned int decimate)
|
2017-10-21 11:05:51 +00:00
|
|
|
{
|
|
|
|
//
|
|
|
|
// 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 ";
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y << " every " << std::to_string(decimate);
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
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 ";
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
cmdstr << "\"" << filename << "\" using "
|
2017-10-21 11:05:51 +00:00
|
|
|
<< 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 ";
|
|
|
|
|
2017-10-24 12:23:59 +00:00
|
|
|
cmdstr << "\"" << filename << "\" using " << column_x << ":" << column_y
|
2017-10-21 11:05:51 +00:00
|
|
|
<< ":" << 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;
|
2017-10-21 11:38:25 +00:00
|
|
|
for(unsigned int iRow = 0; iRow < iHeight; iRow++)
|
2017-10-21 11:05:51 +00:00
|
|
|
{
|
2017-10-21 11:38:25 +00:00
|
|
|
for(unsigned int iColumn = 0; iColumn < iWidth; iColumn++)
|
2017-10-21 11:05:51 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-22 16:05:02 +00:00
|
|
|
Gnuplot& Gnuplot::plot_circle(double east, double north, double radius, const std::string &label)
|
|
|
|
{
|
|
|
|
std::ostringstream cmdstr;
|
|
|
|
//
|
|
|
|
// command to be sent to gnuplot
|
|
|
|
//
|
|
|
|
cmdstr << "set object circle at " + std::to_string(east) + "," + std::to_string(north) + " size " +
|
|
|
|
std::to_string(radius) + " back\n";
|
|
|
|
|
|
|
|
if (label != "")
|
|
|
|
{
|
|
|
|
double east_label = (std::cos(M_PI / 3.0) * radius) * 1.1 + east;
|
|
|
|
double north_label = (std::sin(M_PI / 3.0) * radius) * 1.1 + north;
|
|
|
|
cmdstr << "set label \"" + label + "\" at first " + std::to_string(east_label) +
|
|
|
|
", " + std::to_string(north_label) + " norotate back nopoint offset 0,0\n";
|
|
|
|
}
|
|
|
|
if (nplots > 0)
|
|
|
|
cmdstr << "replot ";
|
|
|
|
else
|
|
|
|
cmdstr << "plot ";
|
|
|
|
|
|
|
|
//
|
|
|
|
// Do the actual plot
|
|
|
|
//
|
|
|
|
cmd(cmdstr.str());
|
|
|
|
|
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2017-10-21 11:05:51 +00:00
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// 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.
|
2017-10-24 12:23:59 +00:00
|
|
|
// The function begins copying from the address specified (str) until it
|
|
|
|
// reaches the terminating null character ('\0'). This final
|
2017-10-21 11:05:51 +00:00
|
|
|
// null-character is not copied to the stream.
|
|
|
|
fputs( (cmdstr+"\n").c_str(), gnucmd );
|
|
|
|
|
|
|
|
// int fflush ( FILE * stream );
|
2017-10-24 12:23:59 +00:00
|
|
|
// 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
|
2017-10-21 11:05:51 +00:00
|
|
|
// 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
|
2017-10-24 12:23:59 +00:00
|
|
|
// Retrieves a C string containing the value of the environment variable
|
|
|
|
// whose name is specified as argument. If the requested variable is not
|
2017-10-21 11:05:51 +00:00
|
|
|
// part of the environment list, the function returns a NULL pointer.
|
|
|
|
#if ( defined(unix) || defined(__unix) || defined(__unix__) ) && !defined(__APPLE__)
|
|
|
|
if (getenv("DISPLAY") == NULL)
|
|
|
|
{
|
|
|
|
valid = false;
|
|
|
|
throw GnuplotException("Can't find DISPLAY variable");
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// if gnuplot not available
|
|
|
|
if (!Gnuplot::get_program_path())
|
|
|
|
{
|
|
|
|
valid = false;
|
|
|
|
throw GnuplotException("Can't find gnuplot");
|
|
|
|
}
|
|
|
|
|
|
|
|
//
|
|
|
|
// open pipe
|
|
|
|
//
|
2017-10-24 12:23:59 +00:00
|
|
|
std::string tmp = Gnuplot::m_sGNUPlotPath + "/" +
|
2017-10-21 11:05:51 +00:00
|
|
|
Gnuplot::m_sGNUPlotFileName;
|
|
|
|
|
|
|
|
// FILE *popen(const char *command, const char *mode);
|
2017-10-24 12:23:59 +00:00
|
|
|
// The popen() function shall execute the command specified by the string
|
|
|
|
// command, create a pipe between the calling program and the executed
|
2017-10-21 11:05:51 +00:00
|
|
|
// command, and return a pointer to a stream that can be used to either read
|
|
|
|
// from or write to the pipe.
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
gnucmd = _popen(tmp.c_str(),"w");
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
gnucmd = popen(tmp.c_str(),"w");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// popen() shall return a pointer to an open stream that can be used to read
|
2017-10-24 12:23:59 +00:00
|
|
|
// or write to the pipe. Otherwise, it shall return a null pointer and may
|
2017-10-21 11:05:51 +00:00
|
|
|
// 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
|
|
|
|
//
|
2017-10-24 12:23:59 +00:00
|
|
|
std::string tmp = Gnuplot::m_sGNUPlotPath + "/" +
|
2017-10-21 11:05:51 +00:00
|
|
|
Gnuplot::m_sGNUPlotFileName;
|
|
|
|
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
if ( Gnuplot::file_exists(tmp,0) ) // check existence
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
if ( Gnuplot::file_exists(tmp,1) ) // check existence and execution permission
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
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
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
stringtok(ls,path,";");
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
stringtok(ls,path,":");
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// 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 defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
if ( Gnuplot::file_exists(tmp,0) ) // check existence
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
if ( Gnuplot::file_exists(tmp,1) ) // check existence and execution permission
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
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,
|
2017-10-24 12:23:59 +00:00
|
|
|
// it returns -1 if the named file does not exist or is not accessible in
|
2017-10-21 11:05:51 +00:00
|
|
|
// 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 defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
if (_access(filename.c_str(), mode) == 0)
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
if (access(filename.c_str(), mode) == 0)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//------------------------------------------------------------------------------
|
|
|
|
//
|
|
|
|
// Opens a temporary file
|
|
|
|
//
|
|
|
|
std::string Gnuplot::create_tmpfile(std::ofstream &tmp)
|
|
|
|
{
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
char name[] = "gnuplotiXXXXXX"; //tmp file in working directory
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
char name[] = "/tmp/gnuplotiXXXXXX"; // tmp file in /tmp
|
|
|
|
#endif
|
|
|
|
|
|
|
|
//
|
|
|
|
// 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
|
2017-10-24 12:23:59 +00:00
|
|
|
// 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
|
2017-10-21 11:05:51 +00:00
|
|
|
// portable filename character set. The characters are chosen such that the
|
2017-10-24 12:23:59 +00:00
|
|
|
// resulting name does not duplicate the name of an existing file at the
|
2017-10-21 11:05:51 +00:00
|
|
|
// time of a call to mkstemp()
|
|
|
|
|
|
|
|
//
|
|
|
|
// open temporary files for output
|
|
|
|
//
|
|
|
|
#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__TOS_WIN__)
|
|
|
|
if (_mktemp(name) == NULL)
|
|
|
|
#elif defined(unix) || defined(__unix) || defined(__unix__) || defined(__APPLE__)
|
|
|
|
if (mkstemp(name) == -1)
|
|
|
|
#endif
|
|
|
|
{
|
|
|
|
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
|