CERN ROOT: Is is possible to plot pairs of x-y data points?

对着背影说爱祢 提交于 2021-01-27 23:32:42

问题


I would like to use CERN ROOT to draw a 2d graph of pairs of x-y datapoints possibly also with y-errorbars. However I only know how to draw histograms.

Is this possible with CERN ROOT? If so how?

Also I realize that there may be better libraries for doing this. I have been using GNUPlot, but unfortunately I can't seem to integrate it well with my C++ code, since I can't find a C/C++ GNUPlot interface which covers all the features and allows me to send data in a bidirectional manner - ie: both to and from GNUPlot.

If you have a better alternative suggestion then that would be most welcome.


回答1:


There is gnuplot iostream to send data from c++ to gnuplot. Within root, you can use (as suggested by the others) TGraph, TGraphErrors, TGraphAsymErrors.

EDIT:

the gnuplot iostream example from its homepage looks like this. Means once you have your data points either as one vector of tuples or as several vectors of floats, you can send them to 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;
}



回答2:


Yes it is possible, you can do it like this:

// 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;

**BUT** This code will NOT work in a loop. The subsequent graphs will be blank. I do not know why.



来源:https://stackoverflow.com/questions/31654406/cern-root-is-is-possible-to-plot-pairs-of-x-y-data-points

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!