Create TGraph from TNtuple

Unfortunately I cannot transform 2 arrays saved in an NTtuple into a TGraph. The example found on the net does not work ( Please help

8000_loss_history_0.06.txt (2.9 KB)
ants.c (1.3 KB)

ROOT Version: 6.12
Platform: Ubuntu
Compiler: Not Provided

The post you are pointing to is a bit old. Try to use this example. It is the same technique but that macro is working (it ran last night to generate the doc)

  TTree *t = new TTree("ntuple", "loss accounts");
  t->ReadFile("8000_loss_history_0.06.txt", "x/F:y:z");
  // t->Print();
  t->Draw("y:x"); // 2D
  TGraph *g = ((TGraph*)(gPad->GetPrimitive("Graph"))); // 2D
  if (g) {
    g = new TGraph(*g); // "disconnect" from the drawn graph
    // g->Print();
1 Like

may be:


“goff” and gPad don’t go very well together.

Why are you drawing the Tree and then catching the output with a graph? (is that even the correct interpretation?)

Search for “Retrieving the result of Draw” and “How to obtain more info from TTree::Draw” in the TTree::Draw method description.

In the example I posted gPad is not involved

In the example I posted the tree is drawn with “goff” the the expressions used in the Draw are retrieved and put in a Graph. It is very close to the first example you posted.

I completely did not understand the example of Wile_E_Coyote, since when I want to extend my plot by another graph I utterly fail. Is it even possible to extend the example for two or multiple graphs?
8000_loss_history_0.06.txt (2.9 KB)
ants.c (1.5 KB)
Ref_loss_history_0.06.txt (2.3 KB)

What does x/F mean?

have you tried the example I pointed ? it is very similar to you 1st post … but working …

I just tried to combine your two examples but it did not work either.
ants.c (1.3 KB)
I am like where I started

void ants() {

   TCanvas* c = new TCanvas();

   Int_t i=0;
   Int_t nlines = 0;
   Float_t x,y,z,a,b;
   ifstream inp;

   auto M = new TMultiGraph();

   TTree *t1 = new TTree("ntuple", "loss accounts");
   t1->ReadFile("8000_loss_history_0.06.txt", "x/F:y:z");

   Int_t n1 = t1->Draw("x:y","","goff");
   printf("The arrays' dimension is %d\n",n1);
   Double_t *X1  = t1->GetVal(0);
   Double_t *Y1  = t1->GetVal(1);

   TTree *t2 = new TTree("ntuple", "loss accounts");
   t2->ReadFile("Ref_loss_history_0.06.txt", "x/F:y:z");

   Int_t n2 = t2->Draw("x:y","","goff");
   printf("The arrays' dimension is %d\n",n2);
   Double_t *X2  = t2->GetVal(0);
   Double_t *Y2  = t2->GetVal(1);

   TGraph *g1 = new TGraph(n1,X1,Y1);
   TGraph *g2 = new TGraph(n2,X2,Y2);




Also TDataFrame would be an other possible approach …

1 Like
  TMultiGraph *mg = new TMultiGraph();
  mg->SetTitle("something magic;its x axis;its y axis");
  TTree *t = new TTree("t", "t");
  t->ReadFile("8000_loss_history_0.06.txt", "x/F:y:z");
  // t->Print();
  t->Draw("y:x"); // 2D
  delete t; // no longer needed
  TGraph *g = ((TGraph*)(gPad->GetPrimitive("Graph"))); // 2D
  if (g) { g->SetLineColor(kRed); mg->Add(new TGraph(*g)); }
  t = new TTree("t", "t");
  t->ReadFile("Ref_loss_history_0.06.txt", "x/F:y:z");
  // t->Print();
  t->Draw("y:x"); // 2D
  delete t; // no longer needed
  g = ((TGraph*)(gPad->GetPrimitive("Graph"))); // 2D
  if (g) { g->SetLineColor(kGreen); mg->Add(new TGraph(*g)); }
1 Like

for completeness, to add to the solutions already proposed and since @couet mentions it, I tried to run RDataFrame on your data.
RDataFrame requires ROOT v6.14 or greater, it’s a fairly new development and as such it still has some rough edges, but it offers a nice high-level syntax for data analysis and manipulation.

To work around some limitations in RDF’s text file processing I had to change the first line of "8000_loss_history_0.06.txt" to 0.0 0.0 0.0 (all floating point zeroes, with a single space in between them): the floating point zero helps RDataFrame to correctly infer the type of your data as double, not int; the single space in between is because variable spacing between fields is not supported (we should add support, I’ll open a bug report about this).

Concretely speaking, you can type this at prompt or put this in a macro:

auto df = ROOT::RDF::MakeCsvDataFrame(/*file=*/"8000_loss_history_0.06.txt",
                                      /*data_delimiter=*/' ');
// if no header is present, your columns are given default names Col0, Col1, ...
auto graph = df.Graph("Col1", "Col0");

or in a one-liner

ROOT::RDF::MakeCsvDataFrame("8000_loss_history_0.06.txt", false, ' ').Graph("Col1", "Col0")->DrawClone("AL");

To display the two graphs together you can add them to a TMultiGraph with multigraph->Add(dataframegraph.GetPtr()):

auto g1 = ROOT::RDF::MakeCsvDataFrame("file1.txt", false, ' ').Graph("Col1", "Col0");
auto g2 = ROOT::RDF::MakeCsvDataFrame("file2.txt", false, ' ').Graph("Col1", "Col0");
TMultiGraph mg;

Hope this helps!


I don’t know what I did wrong. I updated to root version 15.01, added the first line of float zeros and tried your version but my canvas is just blank white.
Ref_loss_history_0.06.txt (2.3 KB)
ANTS.c (922 Bytes)
8000_loss_history_0.06.txt (2.9 KB)

my examples should work as is if you type them at the prompt.
If you used them in a macro, the typical reason why canvases are blank is that the thing you draw went out of scope at the end of the macro: see my reply here.

The easiest way to fix it is to call DrawClone instead of Draw.
Let us know if this fixes it.

Yeah it fixes it but I stumbled over another problem. Adding Zeros at the beginning of my data is okay if the data starts anyway at Zero but in my next example it doesn’t start with zero, it starts at 5.93. Unfortunately the zeros at the beginning lead to a false beginning of the x-axis and additionally a wrong scaling. So how to I remove the zeros of my RDataFrame? I tried changing the range of the x-axis but it did not work :frowning I think one needs to change the settings in the canvas but how?

8000_values.vacuum.txt (8.2 KB)
ANTS.c (1.5 KB)

note that I hadn’t added zeroes, I simply changed the first line of “8000_loss_history_0.06.txt” from 0.0 0 0.0 to 0.0 0.0 0.0 (always one space, always floating point notation).
Can you just do without adding extraneous data (but making sure that you always have a single space between entries in the text file and at least in the first line all numbers are in floating point notation)?


Okay true my bad. That solves the problem and completely leaves my data intact.