First contour from TH2F


I am having trouble getting the first contour from the attached plots- my code is directly taken from the tutorial page and I input the TH2F histogram which is plotted as a contz below. The output of the first contour algorithm is only returning that of the centre region of the histogram and I am unclear why. Could someone please assist? The relevant bit of code from where the histogram was filled to the output of the first contour is below.

Thanks so much

  TH2F *sfr_prob_68 = new TH2F("sfr_prob_68","sfr_prob_68",xnbins,xbins,ynbins,ybins);

  agehere = 0.;
  sfrhere = 0.;
  probhere = 0.;
  int real_pos;
  poscounter = 0;
  for (i = 0; i<point_68; i++) {
    real_pos = position_holder[i];
    agehere = (age_holder[real_pos]);
    sfrhere = (sfr_holder[real_pos]);
    probhere = prob_holder[i];
    summer = summer + probhere;
    //cout << " real_pos is: " << real_pos << " probhere is: " << probhere << endl;

  //  sfr_prob_68->SetContour(2);

  TCanvas *c2 = new TCanvas("c2","First contour",100,100,800,600);
  TObjArray *contours = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
  if (!contours){
    cout << "entered here" << endl;
  TList *lcontour1 = (TList*)contours->At(0);
  if (!lcontour1) return;
  TGraph *gcl1 = (TGraph*)lcontour1->First();
  if (!gcl1) return;
  if (gcl1->GetN() < 10) return;

  TList *lcontour2 = (TList*)contours->At(1);
  if (!lcontour2) return;
  TGraph *gcl2 = (TGraph*)lcontour2->First();
  if (!gcl2) return;
  if (gcl2->GetN() < 10) return;

  int num_points = gcl1->GetN();
  Double_t tg_68_x[num_points];
  Double_t tg_68_y[num_points];
  float graph_68_x[num_points];
  float graph_68_y[num_points];
  for (i=0;i<num_points;i++){
    graph_68_x[i] = TMath::Power(10,tg_68_x[i]);
    graph_68_y[i] = TMath::Power(10,tg_68_y[i]);

TGraph *graph_68 = new TGraph(num_points,graph_68_x,graph_68_y);

Can you please send a running example. With your code I get:

root [0]
Processing firstcont.C...
Error: Symbol xnbins is not defined in current scope  firstcont.C:1:
Error: Symbol xbins is not defined in current scope  firstcont.C:1:
Error: Symbol ynbins is not defined in current scope  firstcont.C:1:
Error: Symbol ybins is not defined in current scope  firstcont.C:1:
*** Interpreter error recovered ***


The full script is below and I also attach the data files.
Thanks so much for the help

Best wishes
fpscomprobsfrhist.txt (199 KB)
model_age.txt (407 Bytes)
sfr_axis.txt (5.86 KB)
sfr_plot.C (6.11 KB)

I downloaded your files. I executed your macro. I get the contour in gray, scale but the canvas supposed to show the first contour is empty. Is it normal ? Can you check the files you sent me ? I am running on Linux with the last ROOT version.
Also your macro gives me the following message:

root [0]
Processing sfr_plot.C...
Note: File "iostream" already loaded
root [1]


there should be 1 last line in the macro:


It was missed in the copying of the macro- sorry about that. You will see it only selects the middle “island” contour and misses the others. Is there a way to get all of the first contours- ie those of the outer most level for all islands?

Thanks so much

Because each “Island” is a contour even if they are on the same altitude. Anyway way a TGraph can be only one curve not several. Have a look at the following example to see how to proceed.

   TCanvas *c  = new TCanvas("c","c",0,0,700,700);

   TF2 *f2 = new TF2("f2","0.1+1000*((1-(x-2)*(x-2))*(1-(y-2)*(y-2)))",1,3,1,3);
   TH2 *h2 = f2->GetHistogram();

   double contours[3];
   contours[0] = 500;
   contours[1] = 700;
   contours[2] = 900;

   Int_t colors[3] = {kRed, kYellow, kGreen};

//   f2->Draw("cont list");
   h2->Draw("cont list");

   TObjArray *conts = (TObjArray*)gROOT->GetListOfSpecials()->FindObject("contours");
   TList* contLevel = NULL;
   TGraph* curv     = NULL;
   Int_t TotalConts = conts->GetSize();

//   f2->Draw("colz");

   for(int i = 0; i < TotalConts; i++){
      contLevel = (TList*)conts->At(i);
      curv = (TGraph*)contLevel->First();
      for(int j = 0; j < contLevel->GetSize(); j++){
         curv->Draw("L same");
         curv = (TGraph*)contLevel->After(curv);

Hi again

Thanks for this example. However, I am not sure I fully understand what it is doing at first glance. For example:

double contours[3];
contours[0] = 500;
contours[1] = 700;
contours[2] = 900;

why/how did you select the 500,700, and 900 for the contour values here? I assume I need to do something similar to select my 2 or 3 islands? Also, I will need a TGraph for each contour that is extracted?
Best wishes

What is interesting for you is the last loop. TotalConts is the total number of contours. The internal loop gets all the graphs belonging to this particular contour.


I put the loop example into the end of the macro we have been testing. There seems to be something wrong- none of the contours that should be extracted as TGraphs are being drawn onto the TH2F colz plot . I have also tried to draw them to their own canvas an the canvas always appears blank. Can you please advise? The new macro is below.

All the best !

root_srf_plot.C (6.74 KB)

  TCanvas *c2 = new TCanvas("c2","First contour",100,100,800,600);
  c2->Draw(); c2->cd();
  for (i = 0; i<TotalConts;i++){
    contLevel = (TList*)conts->At(i);
    curv = (TGraph*)contLevel->First();
    for (j=0;j<contLevel->GetSize();j++){
      cout << "draw level : " << i << "  " << j << endl;
      curv = (TGraph*)contLevel->After(curv);