2

CERN ROOT を使用して、おそらく y-errorbars を使用して xy データポイントのペアの 2D グラフを描画したいと思います。ただし、ヒストグラムの描画方法しか知りません。

これはCERN ROOTで可能ですか? もしそうなら、どのように?

また、これを行うためのより良いライブラリがあるかもしれないことも認識しています。私は GNUPlot を使用していますが、残念ながら、すべての機能をカバーし、双方向でデータを送信できる C/C++ GNUPlot インターフェイスが見つからないため、それを私の C++ コードとうまく統合できないようです。つまり、GNUPlot との間の両方。

より良い代替提案があれば、それは大歓迎です。

4

2 に答える 2

1

c++ から gnuplot にデータを送るgnuplot iostreamがあります。ルート内では、(他の人が示唆しているように)、、、を使用TGraphできTGraphErrorsますTGraphAsymErrors

編集:

ホームページの gnuplot iostream の例は次のようになります。つまり、タプルの 1 つのベクトルまたは float の複数のベクトルとしてデータ ポイントを取得したら、それらを gnuplot に送信できます。

#include <vector>
#include <cmath>
#include <boost/tuple/tuple.hpp>

#include "gnuplot-iostream.h"

int main() {
    Gnuplot gp;
    // Create a script which can be manually fed into gnuplot later:
    //    Gnuplot gp(">script.gp");
    // Create script and also feed to gnuplot:
    //    Gnuplot gp("tee plot.gp | gnuplot -persist");
    // Or choose any of those options at runtime by setting the GNUPLOT_IOSTREAM_CMD
    // environment variable.

    // Gnuplot vectors (i.e. arrows) require four columns: (x,y,dx,dy)
    std::vector<boost::tuple<double, double, double, double> > pts_A;

    // You can also use a separate container for each column, like so:
    std::vector<double> pts_B_x;
    std::vector<double> pts_B_y;
    std::vector<double> pts_B_dx;
    std::vector<double> pts_B_dy;

    // You could also use:
    //   std::vector<std::vector<double> >
    //   boost::tuple of four std::vector's
    //   std::vector of std::tuple (if you have C++11)
    //   arma::mat (with the Armadillo library)
    //   blitz::Array<blitz::TinyVector<double, 4>, 1> (with the Blitz++ library)
    // ... or anything of that sort

    for(double alpha=0; alpha<1; alpha+=1.0/24.0) {
        double theta = alpha*2.0*3.14159;
        pts_A.push_back(boost::make_tuple(
             cos(theta),
             sin(theta),
            -cos(theta)*0.1,
            -sin(theta)*0.1
        ));

        pts_B_x .push_back( cos(theta)*0.8);
        pts_B_y .push_back( sin(theta)*0.8);
        pts_B_dx.push_back( sin(theta)*0.1);
        pts_B_dy.push_back(-cos(theta)*0.1);
    }

    // Don't forget to put "\n" at the end of each line!
    gp << "set xrange [-2:2]\nset yrange [-2:2]\n";
    // '-' means read from stdin.  The send1d() function sends data to gnuplot's stdin.
    gp << "plot '-' with vectors title 'pts_A', '-' with vectors title 'pts_B'\n";
    gp.send1d(pts_A);
    gp.send1d(boost::make_tuple(pts_B_x, pts_B_y, pts_B_dx, pts_B_dy));

    return 0;
}
于 2016-03-31T18:51:42.070 に答える
0

はい、可能です。次のようにできます。

// At program start
TApplication tapp("app", 0, 0); // this is needed for some reason - not ideal

// Later in program
TGraph *tgraph = new TGraph(N, x, y); // data: x,y N points
TCanvas *tcanvas = new TCanvas("tcanvas","canvas title", 200, 10, 800, 600);
tgraph->SetMarkerColor(kBlue);
tgraph->SetMarkerStyle(21);
tgraph->Draw();
tcanvas->Update();

// Wait for user to check if graph is "okay"
std::cin.get();

delete tcanvas;
delete tgraph;

**しかし**このコードはループでは機能しません。後続のグラフは空白になります。何故かはわからない。

于 2015-07-28T11:24:41.423 に答える