#ifndef __GNUPLOT_H__ #define __GNUPLOT_H__ /** * Gnuplotをコントロールするためのヘッダ * * */ #include #include #include #include #include #include #include #ifdef _WIN32 #ifndef GNUPLOT_PATH #define GNUPLOT_PATH "D:\\Tools\\GNU\\gnuplot\\bin\\pgnuplot.exe" #endif #define popen(file, mode) _popen(file, mode) #define pclose(file) _pclose(file) #else #ifndef GNUPLOT_PATH #define GNUPLOT_PATH "/usr/local/bin/pgnuplot.exe" #endif extern "C"{ FILE *popen(char*, char*); void pclose(FILE*); } #endif class GnuplotException : public std::exception{ private: std::string what_str; public: GnuplotException(const std::string &what_arg) : what_str(what_arg){} ~GnuplotException() throw(){} const char *what() const throw(){ return what_str.c_str(); } }; class Gnuplot{ private: FILE *gp; public: // コンストラクタ。 Gnuplot() throw(GnuplotException) : gp(popen(GNUPLOT_PATH, "w")){ if(gp == NULL){throw GnuplotException(std::string("can't find gnuplot."));} } // デストラクタ ~Gnuplot(){ if(gp != NULL){pclose(gp);} } // グラフ出力(string) friend Gnuplot &operator<<(Gnuplot &stream, const std::string &command){ fprintf(stream.gp, command.c_str()); return stream; } // グラフ出力(int) friend Gnuplot &operator<<(Gnuplot &stream, const int &value){ fprintf(stream.gp, "%d", value); return stream; } // グラフ出力(double) friend Gnuplot &operator<<(Gnuplot &stream, const double &value){ fprintf(stream.gp, "%f", value); return stream; } // フラッシュする void flush(){fflush(gp);} }; class GnuplotServer { protected: Gnuplot gp; bool mulitplot_frag; public: GnuplotServer(const std::string &fname) : gp(), mulitplot_frag(false) { std::cerr << "drawing " << fname << "..." << std::endl; gp << "set terminal postscript eps enhanced color\n"; gp << "set output '" << fname << "'\n"; gp.flush(); } ~GnuplotServer() { if(mulitplot_frag){ gp << "set nomultiplot\n"; } gp.flush(); } GnuplotServer &set_multiplot() { mulitplot_frag = true; gp << "set multiplot\n"; return *this; } template GnuplotServer &set(const ParamType ¶m) { gp << "set " << param << "\n"; return *this; } template GnuplotServer &plot(const Fanctor &plotter){ plotter(gp); return *this; } typedef map plot_options_t; template GnuplotServer &plot( const vector > &data, const plot_options_t &options){ gp << "plot '-' "; for(plot_options_t::const_iterator option(options.begin()); option != options.end(); ++option){ gp << option->first << " " << option->second << " "; } if(options.find("title") == options.end()){ gp << "notitle " ; } gp << "\n"; for(typename vector >::const_iterator it(data.begin()); it != data.end(); ++it){ gp << it->first << " " << it->second << "\n"; } gp << "e\n"; return *this; } template GnuplotServer &plot( const vector > &data){ return plot(data, plot_options_t()); } template GnuplotServer &plot( const vector >, plot_options_t> > &data_list){ typedef typename vector >, plot_options_t> > container_t; gp << "plot "; for(container_t::const_iterator it(data_list.begin()); true; ){ gp << "'-' "; for(plot_options_t::const_iterator option(it->second.begin()); option != it->second.end(); ++option){ gp << option->first << " " << option->second << " "; } if(it->second.find("title") == it->second.end()){ gp << "notitle " ; } if((++it) != data_list.end()){ gp << ", "; }else{ break; } } gp << "\n"; for(container_t::const_iterator it(data_list.begin()); true; ){ for(container_t::value_type::first_type::const_iterator it2(it->first.begin()); it2 != it->first.end(); ++it2){ gp << it2->first << " " << it2->second << "\n"; } if((++it) != data_list.end()){ gp << "ee\n"; }else{ break; } } gp << "e\n"; return *this; } }; #endif /* __GNUPLOT_H__ */