gPad->GetUxmin(),GetUxmax() for 2D histogram

Hello.

I am experiencing some inconsistencies with gPad->GetUxmin() and gPad->GetUxmax().
When used with a 1d histogram, the (correct) minimum and maximum values of the x-axis are returned. However for a 2d histogram, they seem to return (some sort of?) NDC values rather than the minimum and maximum values of the x-axis.
Here is a minimal example:

int main() {
  TH2D *h = new TH2D("h","h",100,0,100,100,0,100);
  for (int i=0; i<100; i++) {
    for (int j=0; j<100; j++) {
      h->Fill(gRandom->Gaus(50,10),gRandom->Gaus(50,10));
    }
  }
  TCanvas *canvas1 = new TCanvas("canvas1","canvas1", 1280, 960);
  canvas1->SetLogz();
  h->Draw("cont4z");
  std::cout << "gPad->GetUxmin() = " << gPad->GetUxmin() << std::endl;
  std::cout << "gPad->GetUxmax() = " << gPad->GetUxmax() << std::endl;
  gPad->Update();
  std::cout << "gPad->GetUxmin() = " << gPad->GetUxmin() << std::endl;
  std::cout << "gPad->GetUxmax() = " << gPad->GetUxmax() << std::endl;
  return 0;
}

The gPad->Update(); line is necessary for the 1d histogram-case to give the correct values. The same command changes the output of GetUmin and GetUmax, however still not to the axes values. I am quite sure that I used these commands before successfully.
Could somebody please advise how to obtain the min and max of the x and y axis in a 2d histogram.

Cheers,
Maurits

UPDATE

This seems to be an issue with the command

h->Draw("cont4z");

GetUxmin() and GetUxmax() give correct values if using any other drawing option, such as Draw(“cont3z”) or Draw(“colz”).
Is there a way to have a colored contour plot of a 2d histogram and obtain the (correct) min/max values of the axes?

See how it’s done in the “vertical shaded area” thread: [url]Vertical shaded area

I’ve had a look at the thread you mentioned.
This is how my sample program looks like now

int main() {
  TH2D *h = new TH2D("h","h",100,0,100,100,0,100);
  for (int i=0; i<100; i++) {
    for (int j=0; j<100; j++) {
      h->Fill(gRandom->Gaus(50,10),gRandom->Gaus(50,10));
    }
  }
  TCanvas *canvas1 = new TCanvas("canvas1","canvas1", 1280, 960);
  canvas1->SetLogz();
  // h->Draw("colz");   // THIS WORKS WITHOUT ANY PROBLEMS
  h->Draw("cont4z");   // THIS DOES NOT
  std::cout << "gPad->GetUxmin() = " << gPad->GetUxmin() << std::endl;
  std::cout << "gPad->GetUxmax() = " << gPad->GetUxmax() << std::endl;
  gPad->Update();
  std::cout << "gPad->GetUxmin() = " << gPad->GetUxmin() << std::endl;
  std::cout << "gPad->GetUxmax() = " << gPad->GetUxmax() << std::endl;
  
  TLine *line1 = new TLine(0,0,100,100);
  line1->Draw();

  Double_t bm = canvas1->GetBottomMargin();
  Double_t lm = canvas1->GetLeftMargin();
  Double_t rm = canvas1->GetRightMargin();
  Double_t tm = canvas1->GetTopMargin();
  Double_t x1 = h->GetXaxis()->GetXmin();
  Double_t y1 = h->GetYaxis()->GetXmin();
  Double_t x2 = h->GetXaxis()->GetXmax();
  Double_t y2 = h->GetYaxis()->GetXmax();
  double xmin = x1-(x2-x1)*(lm/(1-rm-lm));
  double ymin = y1-(y2-y1)*(bm/(1-tm-bm));
  double xmax = x2+(x2-x1)*(rm/(1-rm-lm));
  double ymax = y2+(y2-y1)*(tm/(1-tm-bm));
  
  gPad->Update();
  gPad->Range(xmin,ymin,xmax,ymax);
  gPad->Update();
  std::cout << "xmin = " << xmin << std::endl;
  std::cout << "xmax = " << xmax << std::endl;

  TLine *line2 = new TLine(0,0,100,100);
  line2->SetLineColor(kRed);
  line2->Draw();
  return 0;
}

Aside from the fact that the min/max values of the axes are not the correct ones, I assumed that setting a new range of the pad (or canvas) would give me the right frame of reference. This is however not the case. Let me clarify: I would like to get the correct min/max values of the axes in the 2d histogram to ultimately overlay a TGraph onto the 2d histogram. This fails, since ROOT thinks my coordinate system in x and y is ranging from 0 to 1 (or similar), after plotting using the option cont4. The problem disappears if plotting with any other drawing option (cont3, colz etc.)
So maybe I’m missing something?

Two magic words: “transparent pad”.

Here is a working version of your macro:

{
  TH2D *h = new TH2D("h","h",100,0,100,100,0,100);
  for (int i=0; i<100; i++) {
    for (int j=0; j<100; j++) {
      h->Fill(gRandom->Gaus(50,10),gRandom->Gaus(50,10));
    }
  }
  TCanvas *canvas1 = new TCanvas("canvas1","canvas1", 1280, 960);
  canvas1->SetLogz();
  h->Draw("cont4z");
  gPad->Update();
   
  Double_t bm = canvas1->GetBottomMargin();
  Double_t lm = canvas1->GetLeftMargin();
  Double_t rm = canvas1->GetRightMargin();
  Double_t tm = canvas1->GetTopMargin();
  Double_t x1 = h->GetXaxis()->GetXmin();
  Double_t y1 = h->GetYaxis()->GetXmin();
  Double_t x2 = h->GetXaxis()->GetXmax();
  Double_t y2 = h->GetYaxis()->GetXmax();
  
  TPad *null=new TPad("null", "null", 0, 0, 1, 1);
  null->SetFillStyle(0); /* a transparent pad */
  null->SetFrameFillStyle(0);
  null->Draw();
  null->cd();
   
  null->Range(x1-(x2-x1)*(lm/(1-rm-lm)),
              y1-(y2-y1)*(bm/(1-tm-lm)),
              x2+(x2-x1)*(rm/(1-rm-lm)),
              y2+(y2-y1)*(tm/(1-tm-lm)));   
  gPad->Update();
   
  TLine *line2 = new TLine(0,0,100,100);
  line2->SetLineColor(kRed);
  line2->Draw();
}

Thanks couet! It works.
Minor flaw is the segmentation fault which occurs after clicking anywhere on the pad. Also, the histogram cannot be accessed anymore through right clicking on it, as the top layer of the gPad gives details of a TView3D object (the transparent pad I assume?).

I see that too. I’ll check. Thanks for reporting.

Yes there is a transparent pad on top of it hiding the histogram.

Now fixed in the SVN trunk. Thanks for reporting.

Great work. Thanks a lot for the swift replies.

Olivier, I believe your macro contains two small errors.
The “y-low” and “y-high” coordinates for the transparent TPad are miscalculated.
See my last post in the “vertical shaded area” thread.

It looked fine you me. But I did not check closely. May be you are right.
Please post here the version you think is correct in order to avoid to jump
from a post to an other.

null->Range(x1-(x2-x1)*(lm/(1-rm-lm)), y1-(y2-y1)*(bm/(1-tm-bm)), x2+(x2-x1)*(rm/(1-rm-lm)), y2+(y2-y1)*(tm/(1-tm-bm)));

Thanks :slight_smile: