⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gnuplot.cc

📁 penMesh is a generic and efficient data structure for representing and manipulating polygonal meshes
💻 CC
字号:
//////////////////////////////////////////////// A C++ interface to gnuplot. //// This is a direct translation from the C interface// written by N. Devillard (which is available from// http://ndevilla.free.fr/gnuplot/).//// As in the C interface this uses pipes and so wont// run on a system that does'nt have POSIX pipe // support//// Rajarshi Guha// <rajarshi@presidency.com>//// 07/03/03//////////////////////////////////////////////#include "Gnuplot.hh"#include <stdarg.h>#ifdef WIN32#  include <io.h>#else#  include <fcntl.h>  // X_OK#  include <unistd.h> // access#  define PATH_MAXNAMESZ       4096#endif#include <iostream>#include <fstream>#include <sstream>#include <list>#if defined(WIN32)#  define pclose _pclose#  define popen  _popen#  define access _access#  define ACCESS_OK 0#  define PATH_SEP ";"#  define MKTEMP_AND_CHECK_FAILED(name) (_mktemp(name) == NULL)#else#  define ACCESS_OK X_OK#  define PATH_SEP ":"#  define MKTEMP_AND_CHECK_FAILED(name) (mkstemp(name) == -1)#endifusing namespace std;///////////////////////////////// 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>voidstringtok (Container &container, string const &in,           const char * const delimiters = " \t\n"){  const string::size_type len = in.length();  string::size_type i = 0;  while ( i < len )  {    // eat leading whitespace    i = in.find_first_not_of (delimiters, i);    if (i == string::npos)      return;   // nothing left but white space        // find the end of the token    string::size_type j = in.find_first_of (delimiters, i);        // push token    if (j == 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;  }}// ----------------------------------------------------------------------------#ifdef WIN32  std::string Gnuplot::gnuplot_executable_ = "pgnuplot.exe";#else  std::string Gnuplot::gnuplot_executable_ = "gnuplot";#endif// ----------------------------------------------------------------------------Gnuplot::Gnuplot(void){  init();  set_style("points");}// ----------------------------------------------------------------------------Gnuplot::Gnuplot(const string &style){  init();  set_style(style);}// ----------------------------------------------------------------------------Gnuplot::Gnuplot(const string &title,                 const string &style,                 const string &labelx,  const string &labely,                 vector<double> x, vector<double> y){  init();		  if (x.size() == 0 || y.size() == 0)    throw GnuplotException("vectors too small");    if (style == "")    this->set_style("lines");  else    this->set_style(style);    if (labelx == "")    this->set_xlabel("X");  else    this->set_xlabel(labelx);  if (labely == "")    this->set_ylabel("Y");  else    this->set_ylabel(labely);    this->plot_xy(x,y,title);    cout << "Press enter to continue" << endl;  while (getchar() != '\n'){}}// ----------------------------------------------------------------------------Gnuplot::Gnuplot(const string &title,  const string &style,                 const string &labelx, const string &labely,                 vector<double> x){  init();    if (x.size() == 0)    throw GnuplotException("vector too small");  if (!this->gnucmd)    throw GnuplotException("Could'nt open connection to gnuplot");    if (style == "")    this->set_style("lines");    else      this->set_style(style);    if (labelx == "")    this->set_xlabel("X");  else    this->set_xlabel(labelx);  if (labely == "")    this->set_ylabel("Y");  else    this->set_ylabel(labely);    this->plot_x(x,title);    cout << "Press enter to continue" << endl;  while (getchar() != '\n'){}}// ----------------------------------------------------------------------------Gnuplot::~Gnuplot(){  if ((this->to_delete).size() > 0)  {    for (size_t i = 0; i < this->to_delete.size(); i++)      remove(this->to_delete[i].c_str());  }    if (pclose(this->gnucmd) == -1)    cerr << "Problem closing communication to gnuplot" << endl;    return;}// ----------------------------------------------------------------------------bool Gnuplot::get_program_path(const string pname){  list<string> ls;  char *path;    path = getenv("PATH");  if (!path)    return false;  stringtok(ls, path, PATH_SEP);  for (list<string>::const_iterator i = ls.begin(); i != ls.end(); ++i)  {        string tmp = (*i) + "/" + pname;    if ( access(tmp.c_str(), ACCESS_OK) == 0 )      return true;  }  return false;}// ----------------------------------------------------------------------------void Gnuplot::reset_plot(void){         if (this->to_delete.size() > 0)  {    for (size_t i = 0; i < this->to_delete.size(); i++)      remove(this->to_delete[i].c_str());  }  this->nplots = 0;  return;}// ----------------------------------------------------------------------------void Gnuplot::set_style(const string &stylestr){  if (stylestr != "lines" &&      stylestr != "points" &&      stylestr != "linespoints" &&      stylestr != "impulses" &&      stylestr != "dots" &&      stylestr != "steps" &&      stylestr != "errorbars" &&      stylestr != "boxes" &&      stylestr != "boxerrorbars")    this->pstyle = string("points");  else    this->pstyle = stylestr;}// ----------------------------------------------------------------------------void Gnuplot::cmd(const char *_cmd, ...){    va_list ap;    char local_cmd[GP_CMD_SIZE];    va_start(ap, _cmd);    vsprintf(local_cmd, _cmd, ap);    va_end(ap);    strcat(local_cmd,"\n");    fputs(local_cmd,this->gnucmd);    fflush(this->gnucmd);    return;}// ----------------------------------------------------------------------------void Gnuplot::set_ylabel(const string &label){    ostringstream cmdstr;    cmdstr << "set xlabel \"" << label << "\"";    this->cmd(cmdstr.str().c_str());    return;}// ----------------------------------------------------------------------------void Gnuplot::set_xlabel(const string &label){    ostringstream cmdstr;    cmdstr << "set xlabel \"" << label << "\"";    this->cmd(cmdstr.str().c_str());    return;}// ----------------------------------------------------------------------------// Plots a linear equation (where you supply the// slope and intercept)//void Gnuplot::plot_slope(double a, double b, const string &title){    ostringstream stitle;    ostringstream cmdstr;    if (title == "")        stitle << "no title";    else        stitle << title;    if (this->nplots > 0)        cmdstr << "replot " << a << " * x + " << b << " title \"" << stitle.str() << "\" with " << pstyle;    else        cmdstr << "plot " << a << " * x + " << b << " title \"" << stitle.str() << "\" with " << pstyle;    this->cmd(cmdstr.str().c_str());    this->nplots++;    return;}// ----------------------------------------------------------------------------// Plot an equation which is supplied as a string// void Gnuplot::plot_equation(const string &equation, const string &title){    string titlestr, plotstr;    ostringstream cmdstr;    if (title == "")        titlestr = "no title";    else        titlestr = title;    if (this->nplots > 0)        plotstr = "replot";    else        plotstr = "plot";    cmdstr << plotstr << " " << equation << " " << "title \"" << titlestr << "\" with " << this->pstyle;    this->cmd(cmdstr.str().c_str());    this->nplots++;    return;}// ----------------------------------------------------------------------------void Gnuplot::plot_x(vector<double> d, const string &title){  ofstream tmp;  ostringstream cmdstr;#ifdef WIN32  char name[] = "gnuplotiXXXXXX";#else  char name[] = "/tmp/gnuplotiXXXXXX";#endif  if (this->to_delete.size() == GP_MAX_TMP_FILES - 1)  {    cerr << "Maximum number of temporary files reached (" << GP_MAX_TMP_FILES << "): cannot open more files" << endl;    return;  }    //  //open temporary files for output#ifdef WIN32  if ( _mktemp(name) == NULL)#else  if ( mkstemp(name) == -1 )#endif  {    cerr << "Cannot create temporary file: exiting plot" << endl;    return;  }  tmp.open(name);  if (tmp.bad())  {    cerr << "Cannot create temorary file: exiting plot" << endl;    return;  }  //  // Save the temporary filename  //   this->to_delete.push_back(name);  //  // write the data to file  //  for (size_t i = 0; i < d.size(); i++)    tmp << d[i] << endl;  tmp.flush();      tmp.close();    //  // command to be sent to gnuplot  //  cmdstr << ( (this->nplots > 0) ? "replot " : "plot ");  if (title.empty())    cmdstr << "\"" << name << "\" with " << this->pstyle;  else    cmdstr << "\"" << name << "\" title \"" << title << "\" with "            << this->pstyle;    //  // Do the actual plot  //  this->cmd(cmdstr.str().c_str());  this->nplots++;    return;}// ----------------------------------------------------------------------------    void Gnuplot::plot_xy(vector<double> x, vector<double> y, const string &title){  ofstream tmp;  ostringstream cmdstr;#ifdef WIN32  char name[] = "gnuplotiXXXXXX";#else  char name[] = "/tmp/gnuplotiXXXXXX";#endif      // should raise an exception  if (x.size() != y.size())    return;    if ((this->to_delete).size() == GP_MAX_TMP_FILES - 1)  {    std::stringstream s;    s << "Maximum number of temporary files reached ("       << GP_MAX_TMP_FILES << "): cannot open more files" << endl;    throw GnuplotException( s.str() );  }  //open temporary files for output  //  if (MKTEMP_AND_CHECK_FAILED(name))    throw GnuplotException("Cannot create temporary file: exiting plot");  tmp.open(name);  if (tmp.bad())    throw GnuplotException("Cannot create temorary file: exiting plot");    // Save the temporary filename  //   this->to_delete.push_back(name);    // Write the data to file  //  size_t N = std::min(x.size(), y.size());  for (size_t i = 0; i < N; i++)    tmp << x[i] << " " << y[i] << endl;  tmp.flush();      tmp.close();    //  // command to be sent to gnuplot  //  if (this->nplots > 0)    cmdstr << "replot ";  else cmdstr << "plot ";  if (title == "")    cmdstr << "\"" << name << "\" with " << this->pstyle;  else    cmdstr << "\"" << name << "\" title \"" << title << "\" with " << this->pstyle;    //  // Do the actual plot  //  this->cmd(cmdstr.str().c_str());  this->nplots++;    return;}// ----------------------------------------------------------------------------void Gnuplot::init(){  if (!this->get_program_path(gnuplot_executable_))  {    this->valid = false;    throw GnuplotException("Can't find gnuplot in your PATH");  }    this->gnucmd = popen(gnuplot_executable_.c_str(),"w");  if (!this->gnucmd)  {    this->valid = false;    throw GnuplotException("Couldn't open connection to gnuplot");  }  this->nplots = 0;  this->valid = true;}// ============================================================================

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -