codepad
[
create a new paste
]
login
|
about
Language:
C
C++
D
Haskell
Lua
OCaml
PHP
Perl
Plain Text
Python
Ruby
Scheme
Tcl
#pragma once /*! @file @brief gnuplotクラス @author hecomi @date July 12, 2010. ver. 1.02 10/07/05 完成 10/07/12 ログプロット/reset/PNG出力追加 10/07/13 マルチプロット */ #include <vector> #include <fstream> #include <string> /*! @brief gnuplotを扱うライブラリ gnuplotを扱うクラスに関するライブラリです. pgnuplotへとパイプを繋ぎ,関数やデータをgnuplotを用いてプロットする手助けをします. pgnuplot.exeが環境変数へと登録されている必要があります. */ class CGnuplot { private: //! プロットする要素の開始位置と終了位置 FILE* Fp; //! 初期スタイルセットファイル名 static const char* InitialStyleFileName; //! ファイル書き出し時スタイルセットファイル名 static const char* OutputStyleFileName; /*! @brief 一時ファイル名 */ const std::string TempFileName; //! プロットする要素の開始位置と終了位置 template <class Container> struct PlotInfo { Container begin; //!< プロット開始位置 Container end; //!< プロット終了位置 }; /*! @brief プロットタイプ PLOT_TYPE_LINES 線のみ PLOT_TYPE_POINTS 点のみ PLOT_TYPE_LINES_POINTS 線と点 */ enum PLOT_TYPE { PLOT_TYPE_LINES, PLOT_TYPE_POINTS, PLOT_TYPE_LINES_POINTS } PlotType; //! マルチプロットかどうか bool IfMultiplot; //! プロットファイル用ナンバー初期値 static const unsigned int DefaultNo; //! プロットファイル用ナンバー(Temp(No).dat) unsigned int No; //! プロットファイル用ナンバーの最大値 unsigned int MaxNo; //! ファイル名取得 std::string GetPlotFileName(); /*! @brief 初期化 */ void Ini(); /*! @brief バッファフラッシュ */ void Flush(); /*! @brief プロットコマンド */ void Plot(); /*! @brief 1次元要素をプロットする @param[in] x プロット情報を格納したxデータ */ template <class T> void PlotX(PlotInfo<T> x) { T it = x.begin; std::ofstream fout(GetPlotFileName().c_str()); if (fout.fail()) { std::cout << "Error! (@PlotX)" << std::endl; return; } while (it != x.end) { fout << *it << std::endl; it++; } Plot(); } /*! @brief 2次元要素をプロットする @param[in] x プロット情報を格納したxデータ @param[in] y プロット情報を格納したyデータ */ template <class T> void PlotXY(PlotInfo<T> x, PlotInfo<T> y) { T itX = x.begin, itY = y.begin; std::ofstream fout(GetPlotFileName().c_str()); if (fout.fail()) { std::cout << "Error! (@PlotXY)" << std::endl; return; } while (itX != x.end && itY != y.end) { fout << *itX << " " << *itY << std::endl; itX++; itY++; } Plot(); } /*! @brief 3次元要素をプロットする @param[in] x プロット情報を格納したxデータ @param[in] y プロット情報を格納したyデータ @param[in] z プロット情報を格納したzデータ */ template <class T> void PlotXYZ(PlotInfo<T> x, PlotInfo<T> y, PlotInfo<T> z) { T itX = x.begin, itY = y.begin, itZ = z.begin; std::ofstream fout(GetPlotFileName().c_str()); if (fout.fail()) { std::cout << "Error! (@PlotXYZ)" << std::endl; return; } while (itX != x.end && itY != y.end && itZ != z.end) { fout << *itX << " " << *itY << " " << *itZ << std::endl; itX++; itY++; itZ++; } Plot(); } /*! @brief プロットタイプに応じた文字列を取得 */ std::string GetPlotType(); public: /*! @brief コンストラクタ */ CGnuplot(); /*! @brief コンストラクタ 複数のGnuplotを起動した際に,同名のプロットデータファイルが衝突すると, 所望のプロット結果が得られないので,プロットデータファイル名を指定しなければならない. @param[in] fileName プロット時に生成するデータファイルの名前 */ CGnuplot(const char* fileName); /*! @brief デストラクタ */ ~CGnuplot(); /*! @brief 正常に機能しているかどうか */ bool Check(); /*! @brief printfライクにgnuplotのコマンドを実行 @param[in] format printfに用いるフォーマット @param[in] ... 可変長引数 */ void Command(const char* format, ...); /*! @brief 関数をプロット Ex. DrawFunc("sin (x)") @param[in] format プロット対称関数文字列 */ void DrawFunc(const char* func); /*! @brief 1次元要素をプロットする @param[in] cont プロット対称コンテナ */ template <class T, template <class A, class Allocator = std::allocator<A> > class Container> void Plot(Container<T> cont) { PlotInfo<Container<T>::iterator> pi = { cont.begin(), cont.end() }; PlotX(pi); } /*! @brief 1次元要素をプロットする(配列) @param[in] cont プロット対称配列 */ template <class T, int N> void Plot(T (&cont)[N]) { PlotInfo<T*> pi = { &cont[0], &cont[N-1] }; PlotX(pi); } /*! @brief 2次元要素をプロットする @param[in] contX プロット対称コンテナ(x) @param[in] contY プロット対称コンテナ(y) */ template <class T, template <class A, class Allocator = std::allocator<A> > class Container> void Plot(Container<T> contX, Container<T> contY) { PlotInfo<Container<T>::iterator> piX = { contX.begin(), contX.end() }, piY = { contY.begin(), contY.end() }; PlotXY(piX, piY); } /*! @brief 2次元要素をプロットする(配列) @param[in] contX プロット対称配列(x) @param[in] contY プロット対称配列(y) */ template <class T, int N, int M> void Plot(T (&contX)[N], T (&contY)[M]) { PlotInfo<T*> piX = { &contX[0], &contX[N] }, piY = { &contY[0], &contY[M] }; PlotXY(piX, piY); } /*! @brief 3次元要素をプロットする @param[in] contX プロット対称コンテナ(x) @param[in] contY プロット対称コンテナ(y) @param[in] contZ プロット対称コンテナ(z) */ template <class T, template <class A, class Allocator = std::allocator<A> > class Container> void Plot(Container<T> contX, Container<T> contY, Container<T> contZ) { PlotInfo<Container<T>::iterator> piX = { contX.begin(), contX.end() }, piY = { contY.begin(), contY.end() }, piZ = { contZ.begin(), contZ.end() }; PlotXYZ(piX, piY, piZ); } /*! @brief 3次元要素をプロットする(配列) @param[in] contX プロット対称配列(x) @param[in] contY プロット対称配列(y) @param[in] contZ プロット対称配列(z) */ template <class T, int N, int M, int L> void Plot(T (&contX)[N], T (&contY)[M], T (&contZ)[L]) { PlotInfo<T*> piX = { &contX[0], &contX[N] }, piY = { &contY[0], &contY[M] }, piZ = { &contZ[0], &contZ[L] }; PlotXYZ(piX, piY, piZ); } /*! @brief 2次元マルチプロット(STLコンテナ限定)(x軸共通) @param[in] x プロット用x軸ベクトル @param[in] ys yベクトルの集合 */ template <class T, template <class A, class Allocator = std::allocator<A> > class Container> void Multiplot(Container<T> x, Container<std::pair<std::string, Container<T> > > ys) { // 念のため No = DefaultNo; // プロット開始 Command("plot \\"); // ファイルへ書き出し std::ofstream fout(GetPlotFileName().c_str()); if (fout.fail()) { std::cout << "Error! (@Multiplot)" << std::endl; return; } // 第2引数の展開 Container<std::pair<std::string, Container<T> > >::iterator itYs = ys.begin(); unsigned int i = 1; while (itYs != ys.end()) { // ペアの展開 std::pair<std::string, Container<T> > pair = *itYs; std::string title = pair.first; Container<T> y = pair.second; // イテレータ指定 Container<T>::iterator itX = x.begin(), itY = y.begin(); while (itX != x.end() && itY != y.end()) { fout << *itX << " " << *itY << std::endl; itX++; itY++; } fout << std::endl << std::endl; // プロット Command("'%s' ind %d w %s ls %d ti '%s'\\", GetPlotFileName().c_str(), i-1, GetPlotType().c_str(), i, title.c_str()); if (i < ys.size()) { Command(",\\"); } else { Command(""); break; } itYs++; i++; } } /*! @brief 2次元マルチプロット(STLコンテナ限定)(x軸別) @param[in] plot プロットデータ */ template <class T, template <class A, class Allocator = std::allocator<A> > class Container> void Multiplot(Container<std::pair<std::string, std::pair<Container<T>, Container<T> > > > plot) { // 念のため No = DefaultNo; // プロット開始 Command("plot \\"); // ファイルへ書き出し std::ofstream fout(GetPlotFileName().c_str()); if (fout.fail()) { std::cout << "Error! (@Multiplot)" << std::endl; return; } // 第2引数の展開 Container<std::pair<std::string, std::pair<Container<T>, Container<T> > > >::iterator it = plot.begin(); unsigned int i = 1; while (it != plot.end()) { // ペアの展開 std::pair<std::string, std::pair<Container<T>, Container<T> > > pair = *it; std::string title = pair.first; Container<T> x = pair.second.first; Container<T> y = pair.second.second; // イテレータ指定 Container<T>::iterator itX = x.begin(), itY = y.begin(); while (itX != x.end() && itY != y.end()) { fout << *itX << " " << *itY << std::endl; itX++; itY++; } fout << std::endl << std::endl; // プロット Command("'%s' ind %d w %s ls %d ti '%s'\\", GetPlotFileName().c_str(), i-1, GetPlotType().c_str(), i, title.c_str()); if (i < plot.size()) { Command(",\\"); } else { Command(""); break; } it++; i++; } } /*! @brief プロットタイプ(線,点,線と点)をセット */ void SetPlotType(PLOT_TYPE plotType); /*! @brief マルチプロット(複数の図をプロット)の切り替え @param[in] sw true: マルチプロット false: 解除 */ void SetMultiplot(bool sw = true); /*! @brief ラベルをセット @param[in] title タイトル */ void SetTitle(const char* title); /*! @brief ラベルをセット @param[in] labelX Xラベル名 @param[in] labelY Yラベル名 */ void SetLabel(const char* labelX, const char* labelY); /*! @brief プロット範囲を指定 @param[in] min x軸プロット範囲最小値 @param[in] min y軸プロット範囲最小値 */ void SetXRange(const double min, const double max); /*! @brief プロット範囲を指定 @param[in] min y軸プロット範囲最小値 @param[in] min y軸プロット範囲最小値 */ void SetYRange(const double min, const double max); /*! @brief リプロット */ void Replot(); /*! @brief 設定全リセット */ void Reset(); /*! @brief 片対数プロットに変更 */ void SetLogPlotY(bool sw = true); /*! @brief 現在プロットしているデータをファイルに書き出す 中身はTempFileNameに保存されているデータをコピーしているだけ @param[in] fileName 書き出し先ファイル名 */ void DumpToFile(const char* fileName); /*! @brief 現在プロットしているデータをEPSで書き出す @param[in] fileName 書き出し先ファイル名 */ void DumpToEps(const char* fileName); /*! @brief 現在プロットしているデータをPNGで書き出す @param[in] fileName 書き出し先ファイル名 */ void DumpToPng(const char* fileName); /*! @brief 外部ファイルからコマンドを読み込み実行 @param[in] fileName 読み込み元ファイル名 */ void CommandFromFile(const char* fileName); };
Private
[
?
]
Run code
Submit