Plotting the differences between two graphs

Please provide the following information:


ROOT Version (e.g. 6.12/02): 6.12/04
Platform, compiler (e.g. CentOS 7.3, gcc6.2): CENTOS 7


Hello I would like to plot differences between two graphs that have drawn with TGraph.

Is there any way to do this? I tried by adding “Add(fluka_lead,-1)” but it is not working

Just to be understood, I attach the code. Be warned it is bit messy because of different binning between two difference sets of data

Float_t  E1box1, E2box1 , Ybox1, EYbox1;

 Double_t EnergyBox1[459];
 Double_t eEnergyBox1[459];
 Double_t FluenceBox1[459];
 Double_t eFluenceBox1[459];
 // per primary
 double Norm = 1.0;
 double sum=0;
 double esum=0;
  ifstream infile("fluka_lead.data");
  double emin=0;
  double emax=0;
for (int i=0; i<458; i++){
  infile >>  E1box1 >> E2box1 >> Ybox1 >> EYbox1;
//   printf("%g\n",E1box1/E2box1);
  if(!i) emin = E1box1;
  if(i==457) emax = E2box1;
  EnergyBox1[i] = (E2box1+E1box1)/2;
  eEnergyBox1[i] = 0;
  FluenceBox1[i] = Norm*Ybox1*(E2box1-E1box1)/(log(E2box1)-log(E1box1));
  eFluenceBox1[i] = Norm*0.01*EYbox1*Ybox1*(E2box1-E1box1);
  sum+=Ybox1*(E2box1-E1box1);
}
infile.close();
  printf("sum = %g\n",sum);



  TGraphErrors* fluka_lead = new TGraphErrors(458,EnergyBox1,FluenceBox1,eEnergyBox1,eFluenceBox1);
 fluka_lead->SetMarkerSize(0.8);
 fluka_lead->SetMarkerColor(kRed);
 fluka_lead->SetMarkerStyle(20);
 fluka_lead->SetLineColor(kRed);
 fluka_lead->Draw("PLZ");

// printf("%g, %g\n",EnergyBox1[0],EnergyBox1[356]);

 TGraph *geant_lead = new TGraph();
 TH1F *h1 = new TH1F("f","G4 results",458,log(emin),log(emax));
 ifstream file1("lead_geant4.txt");
int i=0;
double x1;
int nlines = 0;
  while(!file1.eof()) {
    nlines++;
    file1>>x1;
    h1->Fill(log(x1*1e-3));}
 double integral = nlines/20000.;

 sum=0;
 double deltalog = (log(emax)-log(emin))/458.;
 for(int i=0;i<458;++i) {
     double elow = exp(log(emin)+deltalog*i);
     double ehigh = exp(log(emin)+deltalog*(i+1));
     sum += h1->GetBinContent(i)*(log(ehigh)-log(elow));
    // printf("%g %g\n",x,h1->GetBinContent(i));
  }
 printf("sum=%g\n",sum);
for(int i=0;i<458;++i) {
     double x = exp(h1->GetBinCenter(i));
     double elow = exp(log(emin)+deltalog*i);
     double ehigh = exp(log(emin)+deltalog*(i+1));
     geant_lead->SetPoint(i,x,h1->GetBinContent(i)*integral/sum);
 }
 geant_lead->SetMarkerColor(kBlue);
 geant_lead->SetMarkerStyle(21);
 geant_lead->SetLineColor(kBlue);
 geant_lead->SetMarkerSize(0.8);
 geant_lead->Draw("PLZ");
 h1->SetMaximum(100);
 h1->SetMinimum(1e-9);
 TCanvas *c2 = new TCanvas();
 c2->SetLogy();
 h1->Draw();

  TCanvas *c3 = new TCanvas();
  geant_lead->Add(fluka_lead,-1)

Reading your code it is not completely clear where/how you are doing “the difference between two graphs”. Do you want to do the difference between geant_lead and fluka_lead ? I so I would guess that it would be enough to create a new TGraph called diff and to set its points as: diff[i] = geant_lead[i]-fluka_lead[i].

Yes that is correct.

Thank you . I know the code is complex. It is because of the sorting out the different binning when i plot the data.

Thank you for your insight. I thought there is a way like using Add(fluka_lead,-1)

Note that the solution proposed by Olivier assumes that both graphs have exactly the same numbers of points and that their X coordinates are exactly the same (for all points).

If any of the above conditions is not met, try:

{
  // Note: this macro needs ROOT 6
  
  // define some variables used below
  Double_t x[100], y[100];
  Int_t n;
  
  // create the first graph
  n = 22;
  for (Int_t i = 0; i < n; i++) {
    x[i] = i * TMath::Pi() / (n - 1.);
    y[i] = TMath::Sin(x[i]);
  }
  TGraph *geant_lead = new TGraph(n, x, y);
  geant_lead->SetTitle("geant_lead;X;Y");
  
  // create the second graph
  n = 33;
  for (Int_t i = 0; i < n; i++) {
    x[i] = i * TMath::Pi() / (n - 1.);
    y[i] = TMath::Cos(x[i]);
  }
  TGraph *fluka_lead = new TGraph(n, x, y);
  fluka_lead->SetTitle("fluka_lead;X;Y");
  
  // create the difference graph
  std::vector<Double_t> v;
  v.insert( v.end(), geant_lead->GetX(), (geant_lead->GetX() + geant_lead->GetN()) );
  v.insert( v.end(), fluka_lead->GetX(), (fluka_lead->GetX() + fluka_lead->GetN()) );
  std::sort( v.begin(), v.end() );
  v.erase( std::unique( v.begin(), v.end() ), v.end() );
  n = v.size();
  TGraph *diff_lead = new TGraph(n);
  for (Int_t i = 0; i < n; i++)
    diff_lead->SetPoint( i, v[i], (geant_lead->Eval(v[i]) - fluka_lead->Eval(v[i])) );
  diff_lead->SetTitle("geant_lead - fluka_lead;X;#Delta Y");
  
  // draw everything
  TCanvas *c = new TCanvas("c", "c");
  c->Divide(1, 3);
  c->cd(1);
  geant_lead->Draw("AL*");
  c->cd(2);
  fluka_lead->Draw("AL*");
  c->cd(3);
  diff_lead->Draw("AL*");
  c->cd(0);
}

Thank you so much. I will try the string that you used in last few lines introducing new TGraphs.

Several posts referred to be using Add ( x , -1); to subtract two graphs but it did not work for me.

Thank you

The TGraph class does not have an “Add” method . Which “Add” are you talking about ?

I think people quite often mix graphs with histograms.

The Add in histogram I guess as Wile_E_Coyote suggested.

Thank you

Ok … but you are working with TGraph …So there is no Add()

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.