2011-01-16 14 views
3

私はDan Stahlkeのgnuplot C++ I/Oインターフェイスにアクセスしました。残念なことに、あまりにも例がありませんし、実際のドキュメントがありません。C++からgnuplotにデータを渡す例(Gnuplot-iostreamインターフェイスを使用)

私はC++プロジェクトで、次のデータ型があります。私はデータ(X軸上の日付、および3つの数字をプロットすることができるように、C++からのデータセットの変数を渡したい

struct Data 
{ 
    std::string datestr; // x axis value 
    float f1;    // y axis series 1 
    float f2;    // y axis series 2 
    float f3;    // y axis series 3 
}; 


typedef std::vector<Data> Dataset; 

をY軸上に時系列としてプロットされる)。

データセット変数をC++からgnuplot(Gnuplot-iostreamインターフェイスを使用して)に転送し、渡されたデータを使用して簡単なプロットを作成する方法を教えてもらえますか?

答えて

1

あなたはgnuplotの-のiostreamが付属しての例を見ていましたか?

彼らはまばらですが、彼らは一連のデータポイントからプロットを作成する方法を示しています。それは簡単なようにカスタムデータ型をサポートすることができ、私は最近のgitに新しいバージョンをプッシュしている

Gnuplot gp; 

gp << "set terminal png\n"; 

std::vector<double> y_pts; 
for(int i=0; i<1000; i++) { 
    double y = (i/500.0-1) * (i/500.0-1); 
    y_pts.push_back(y); 
} 

gp << "set output 'my_graph_1.png'\n"; 
gp << "plot '-' with lines, sin(x/200) with lines\n"; 
gp.send(y_pts); 
5

をこの。 struct Dataをサポートするには、TextSenderクラスの特化を提供することができます。ここでは、定義した構造体を使用した完全な例を示します。

 
#include <vector> 
#include "gnuplot-iostream.h" 

struct Data { 
    std::string datestr; // x axis value 
    float f1;    // y axis series 1 
    float f2;    // y axis series 2 
    float f3;    // y axis series 3 
}; 

typedef std::vector<Data> Dataset; 

namespace gnuplotio { 
    template<> 
    struct TextSender<Data> { 
     static void send(std::ostream &stream, const Data &v) { 
      TextSender<std::string>::send(stream, v.datestr); 
      stream << " "; 
      TextSender<float>::send(stream, v.f1); 
      stream << " "; 
      TextSender<float>::send(stream, v.f2); 
      stream << " "; 
      TextSender<float>::send(stream, v.f3); 

      // This works too, but the longer version above gives 
      // gnuplot-iostream a chance to format the numbers itself (such as 
      // using a platform-independent 'nan' string). 
      //stream << v.datestr << " " << v.f1 << " " << v.f2 << " " << v.f3; 
     } 
    }; 
} 

int main() { 
    Dataset x(2); 
    // The http://www.gnuplot.info/demo/timedat.html example uses a tab between 
    // date and time, but this doesn't seem to work (gnuplot interprets it as 
    // two columns). So I use a comma. 
    x[0].datestr = "01/02/2003,12:34"; 
    x[0].f1 = 1; 
    x[0].f2 = 2; 
    x[0].f3 = 3; 
    x[1].datestr = "02/04/2003,07:11"; 
    x[1].f1 = 10; 
    x[1].f2 = 20; 
    x[1].f3 = 30; 

    Gnuplot gp; 
    gp << "set timefmt \"%d/%m/%y,%H:%M\"\n"; 
    gp << "set xdata time\n"; 
    gp << "plot '-' using 1:2 with lines\n"; 
    gp.send1d(x); 

    return 0; 
} 

バイナリ形式でデータを送信するのをサポートするために同様のことを行うことができます。例については、git repoのexample-data-1d.ccを参照してください。

また、このようなカスタムデータ型は、operator<<(std::ostream &, ...)をオーバーライドすることでサポートできます。

別のオプションは、独自の構造体を定義する代わりにstd::tuple(C++ 11で利用可能)またはboost::tupleを使用することです。これらは箱の外でサポートされています(さて、今はあなたが質問した時点ではありませんでした)。

関連する問題