(追記: 11/1/19)
最新版はこちらになります:d:id:hecomi:20101209:1291888423
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- -
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
C++からgnuplotをパイプをつなげて使用するクラス,CGnuplotを作成しましたが(id:hecomi:20100709:1278686045),マルチプロットも出来るようにしたのでご紹介します.
gnuplot.h: http://codepad.org/WwhXAuuy
gnuplot.cpp: http://codepad.org/5v7DKGaM
NYSLライセンスなので,気が向いたらどうぞ.
マルチプロットするための2つの手法
gnuplotには,複数のグラフをプロットする為に2つの方法が用意されています.
multiplotの使用
1つは,set multiplotを使用する方法です.
gnuplot > set multiplot gnuplot > set xrange[-1:1] gnuplot > set yrange[-1:1] multiplot > plot x*x multiplot > plot x*x*x multiplot > unset multiplot gnuplot >
ただ,完全にグラフを重ねあわせるだけですので,縦軸がずれる場合はグラフが汚くなってしまいますので,rangeをセットしておく必要があります.
これをCGnuplotを用いると次のように書けます.コードは数値計算を前提に,vectorに代入したものを用いています.makeVectorとsetVectorはid:hecomi:20100712:1278892595に書いてあります.
vector<double> x, y1, y2; // -1〜1を100等分したベクトルを作成 makeVector(x, -1.0, 1.0, 100); // boost::lambdaを用いて,x^2とx^3のベクトルを作成 setVector(y1, x, _1*_1); setVector(y2, x, _1*_1*_1); // CGnuplotによるマルチプロット CGnuplot gp; gp.SetMultiplot(); gp.SetXRange(-1.0, 1.0); gp.SetYRange(-1.0, 1.0); gp.Plot(x, y1); gp.Plot(x, y2); gp.SetMultiplot(false);
となります.ただし凡例に付いては重なって汚くなってしまうため,機能に追加しておりません.凡例を付けたい場合は,次のMultiplotメンバ関数を使用してください.簡単にプロットしたい場合はsetMultiplotを利用することをお勧めします.
plot A, B, C...
2つ目は,plotをカンマ区切りで利用する方法です.こちらではタイトルを重ねずに表示できることから,凡例を表示したい場合におすすめです.
gnuplot > set xrange[-1:1] gnuplot > set yrange[-1:1] gnuplot > plot x*x ti "y = x^2", x*x*x ti "y = x^3"
これをC++で書くと次のようになります.ちょっと手間がかかります.
vector<double> x, y1, y2; // -1〜1を100等分したベクトルを作成 makeVector(x, -1.0, 1.0, 100); // boost::lambdaを用いて,x^2とx^3のベクトルを作成 setVector(y1, x, _1*_1); setVector(y2, x, _1*_1*_1); // std::pairにfirst: 凡例名, second: vectorで入れる pair<string, vector<double> > pair1("y = x^2", y1), pair2("y = x^3", y2); // std::vector<std::pair>に格納 vector<pair<string, vector<double> > > plotData; plotData.push_back(pair1); plotData.push_back(pair2); // CGnuplotによるマルチプロット CGnuplot gp; gp.SetXRange(-1.0, 1.0); gp.SetYRange(-1.0, 1.0); gp.Command("set key right bottom"); gp.Multiplot(x, plot Data);
となります.もっと良いプロット方法無いですかね….ちょっとpairの入ったvectorが気持ち悪いので….
ちなみにPNG/EPS出力も以下のようにすれば可能です.
// とりあえずラベルをつけておく gp.SetLabel("x", "y"); // EPS出力 gp.DumpToEps("plotData"); // gp.DumpToPng("plotData"); // PNG出力
補足:初期化ファイル
コンストラクタで「macro\initial.txt」,EPS出力時に「macro\output_line.txt」を読み込むようにしています.これは次のようなファイルを読み込んでいます.
initial.txt
set style line 1 linetype 1 linewidth 2 set style line 2 linetype 2 linewidth 2 set style line 3 linetype 3 linewidth 2 set style line 4 linetype 4 linewidth 2 set style line 5 linetype 5 linewidth 2 set style line 6 linetype 6 linewidth 2 set style line 7 linetype 7 linewidth 2 set style line 8 linetype 8 linewidth 2 set style line 9 linetype 9 linewidth 2 set style line 10 linetype 10 linewidth 2
output_line.txt
set style line 1 linetype 1 linewidth 6 set style line 2 linetype 2 linewidth 6 set style line 3 linetype 3 linewidth 6 set style line 4 linetype 4 linewidth 6 set style line 5 linetype 5 linewidth 6 set style line 6 linetype 6 linewidth 6 set style line 7 linetype 7 linewidth 6 set style line 8 linetype 8 linewidth 6 set style line 9 linetype 9 linewidth 6 set style line 10 linetype 10 linewidth 6
最後に
興味が向いたら,使って頂けると嬉しいです.フィードバックも頂ければ幸いです.
マニュアルについてはDoxygenを通せば生成されると思いますので,メンバ一覧を見たい方はインストールしてマニュアルを生成してみてください.
追記 10/07/16
これだと,x軸のベクトルが同じでない場合のプロットが出来ないですね.
新たなダウンロード先は以下になります.
gnuplot.h : http://codepad.org/TrefNHjy