How to plot two histograms from two .root files and save as .png in a loop?


ROOT Version 6.08/04:
Platform, compiler (Xubuntu 17.04, gcc6.3):


New to the forums and ROOT, please let me know if I should ask differently.

I’m trying to loop over histograms from two different .root files and plot them in the same canvas with two pads. I then want to save the canvas to a .png file. Rinse and repeat.

I am unsure how the conditional should function.
If the histogram comes from file:
TFile* hfdm = new TFile(“histogram_emc.root”);
I want it to plot in pad one (c1_1->Draw())

If the histogram comes from file:
TFile* dhfdm = new TFile(“dhistogram_emc.root”);
I want it to plot in pad two (c1_2->Draw())

Both histograms in the two files are named hfdm1/2/3… because they plot the same variables (i.e. energies). One is for a single-photon event and the other for a pion-decay event however. That is why I want to plot them side by side to be able to compare their information.

I am also unsure how to put image creation in the loop (img1, img2, img3 etc). And how to save them under different names (hfdm1.png, hfdm2.png, etc.)

Code so far:

TFile* hfdm = new TFile("histogram_emc.root"); // Load file containing histograms
TH2F* hfdm1 = (TH2F *) h->Get("hfdm1"); // Retrieve histogram 1
... etc

TFile* dhfdm = new TFile("dhistogram_emc.root"); // Load file containing dual-photon histograms
TH2F* dhfdm1 = (TH2F *) h->Get("hfdm1"); // Retrieve histogram 1
... etc

char name[20];
  for (int j=0; j<N; j++)
    {
      TCanvas *c1 = new Tcanvas;
      c1->Divide(2,1);
      c1->SetGrid();
      
      if (sprintf(name, "%s%d", "hfdm", j))
	{
	  TH2F *h = (TH2F*)gDirectory->Get(name);
	  c1_1->cd();
	  (TH2F*)name->Draw("Color");
	  
	}
      else if (sprintf(name, "%s%d", "dhfdm", j))
	{
	  TH2F *h = (TH2F*)gDirectory->Get(name);
	  c1_2->cd();
	  (TH2F*)name->Draw("Color");
	}
      
      TImage* img1 = TImage::Create();
      img1->FromPad(c1);
      img1->WriteImage("./Histogram_Images/hfdm1.png");
      delete c1;
      delete img1; // this should be looped somehow
    }

Let me know if anything is unclear, thanks!

Try:

{
  TFile *f1 = TFile::Open("histogram_emc.root");
  TFile *f2 = TFile::Open("dhistogram_emc.root");
  gROOT->cd();
  TCanvas *c = new TCanvas("c");
  c->Divide(2, 1);
  Int_t N = 3; // draw histograms 1 ... N
  for(Int_t i = 1; i <= N; i++) {
    const char *o = ((i == 1) ? "BOX" : "COL");
    TString n = TString::Format("hfdm%d", i);
    TH2F *h;
    c->cd(1);
    f1->GetObject(n, h);
    if (h) h->Draw(o);
    // gPad->SetGrid(1, 1);
    c->cd(2);
    f2->GetObject(n, h);
    if (h) h->Draw(o);
    // gPad->SetGrid(1, 1);
    c->cd(0);
    c->SaveAs(n + ".png");
  }
  delete c;
  delete f1;
  delete f2;
}
2 Likes

That actually works! Thank you kindly for your reply and time :slight_smile:

As a quick follow up question. Is there an easy way to differentiate drawing options? Say I want hfdm1 to Draw(“Box”) but hfdm2 to Draw(“COL”). Would I be able to implement that in the loop?

Edit: A switch statement works:

c->cd(1);
    f1->GetObject(n, h);
    switch (i) {
    case 1 :
      if (h) h->Draw("COL");
      break;
    default :
      if (h) h->Draw("BOX");
    }
      gPad->SetGrid(1, 1);

Is this a good way to go about it?

I modified the example source code in my previous post here.

1 Like

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