Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 381
FreelanceConsultant Avatar asked Oct 17 '25 11:10

FreelanceConsultant


1 Answers

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;
}
like image 157
pseyfert Avatar answered Oct 19 '25 02:10

pseyfert



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!