TGraph2D with predefined axis-range?

Hi,
I would like to create a TGraph2D and draw it with a prefined axis range (using cont4z). I can limit the axis, but I cannot extend them…?
Finally, I would like to draw some lines, circles and arcs on top.

I found this:

but using the SetHistogram() causes a crash

c1->cd(1);
//gPad->DrawFrame(-125/2,-65/2,125/2,65/2);
TH2I *h = new TH2I("h","h",10,-125./2,125./2,10,-65./2,65./2);
gr->SetHistogram(h);
//h->Draw("cont4z");
gr->Draw("cont4z");
//gr->GetXaxis()->SetRange(-125/2,125/2);
TLine *l1 = new TLine(-0.5,0,0.5,0); l1->Draw();

the gPad Stuff causes strange behaviour of the axis ticks…
and finally the line is not in the coordinate system of the TGraph…wtf

I’m searching for something like SetLimits()

Thanks
Georg
_ROOT Version:_6.28/06
Platform: Windows
Compiler: VS

Hi,
I think that SetHistogram cause a crash because the argument is a 1D histogram.

Have you tried to simply draw the histogram and then draw the graph with cont4z and the same option?

h->Draw();
gr->Draw("cont4z same");

I would also advise to create a 2-D histogram, set axes, axis titles etc as desired, draw it, and draw the graph on top. That’s because internally, the graph does the same, but only with a default axis range.

…interesting…took me a while to figure this out:

I tried to create a minimal example and wasn’t able to reproduce the error, now I got it.
I’m drawing the histro and graph inside a Loop()-method, which was initially created by TTree::MakeClass.

Seems that some directories and paths are bent when using these constructions - I had a similar issue in the past (see here: Histograms not drawn inside Looper-Class)

indeed

gROOT->cd(); 

before histocreation solves the issue.
Same applies to

h->SetDirectory(NULL);

after histocreation.
I was wondering why

TFile *outfile = new TFile("out.root","RECREATE");
TDirectory *dir = outfile;
dir->cd();

before the histocreation is not working

Georg

Another one:
As mentioned before I would like to draw some TLine above.
Whren drawing ontop of the histogram this works, but when drawing on the TGraph the coordinates are differing. Is there a good method to realign the coordinate-system?

Georg

Hello @Georg_T,

the global directory is indeed a thing that is a bit :man_shrugging: in ROOT. The problem you seem to encounter is that when opening a file, and creating the histogram, the histogram is associated to the file. When you close the file, the histogram disappears.

This is equivalent to outfile->cd(), so that’s what you might not want because the histogram is now associated to the file.

Indeed, this will solve the issue because now, if you create a histogram, it’s associated to the ROOT session, so it doesn’t disappear when you close a file.

This is the best solution. Now, no attempt will be made by ROOT to manage to lifetime of the histogram. This is what I would generally recommend.

I believe this has to do with the two coordinate systems. One is the normalised device coordinates (NDC) see here, the other one is the coordinate system spanned by the histogram.

If you draw a line “just like this”, it’s drawn in the histogram coordinate system, but if there’s no histogram, that might fail. If you go for NDCs, the line will be in the same place on the canvas independent of the underlying pad.

Do you have a minimal example showing the problem you encounter to draw a TLine above the TGraph2D ?

Here an easy to understand example showing the different behaviour of the TLine

int test() {
	
	TCanvas *c1 = new TCanvas("c1","c1",1200,800);
	c1->Divide(2,2);
	//Line above Histo
	c1->cd(1);
	TH2I *h = new TH2I("h","h",10,0,10,10,0,10);
	h->Fill(5,5);
	TLine *l1 = new TLine(1,1,2,3); //In coordinates of the histogram
	h->Draw("col");
	l1->Draw();
	
	
	c1->cd(2);
	//line above TGraph
	TGraph2D *gr = new TGraph2D();
	gr->AddPoint(0,0,3);
	gr->AddPoint(0,5,4);
	gr->AddPoint(5,0,5);
	gr->AddPoint(5,5,5);
	gr->Draw("cont4z");
	TLine *l2 = new TLine(-0.5,0,0.5,0); //in unknown coordinate system
	l2->Draw();
	
	c1->cd(3);
	//line above Graph above Histo
	TGraph2D *gr2 = new TGraph2D();
	gr2->AddPoint(0,0,3);
	gr2->AddPoint(0,5,4);
	gr2->AddPoint(5,0,5);
	gr2->AddPoint(5,5,5);
	TH2I *h2 = new TH2I("h2","h2",10,0,10,10,0,10);
	gr2->SetHistogram(h2);
	h2->Draw();
	TLine *l3 = new TLine(-0.5,0,0.5,0); //in unknown coordinate system
	gr2->Draw("cont4z same");
	l3->Draw();
	return 0;
}

Maybe there is an easy method how to enforce the TLine in the histocoordinate system?
Georg

I see, you are using CONT4. This contour option indeed is the one using its own corrdinates system and the values on the axis do not corespond to the pad’s coordinates. You can see that with the event status tool. In order to have the same coordinates for your line (or marker) you will need to draw a pad on top. I havee an example doing that. Here it is:

{
   int N=0;
   int minx=0; int miny=0; int minz=0;
   double z;
   auto dt4 = new TGraph2D();

   // Fill Graph
   for (Double_t m=-1000.; m<1000.; m+=100) {
       for (Double_t A=0; A<3; A+=0.05) {
           z = sin(A);
           dt4->SetPoint(N,m,A,z);
           N++;
           if (z < minz){ // Look for minimum
               minz = z;
               minx = m;
               miny = A;
           }
       }
   }

   dt4->Draw("CONT4Z");

   // Draw a marker
   Double_t BM = gPad->GetBottomMargin();
   Double_t LM = gPad->GetLeftMargin();
   Double_t RM = gPad->GetRightMargin();
   Double_t TM = gPad->GetTopMargin();
   Double_t X1 = hist4->GetXaxis()->GetXmin();
   Double_t Y1 = hist4->GetYaxis()->GetXmin();
   Double_t X2 = hist4->GetXaxis()->GetXmax();
   Double_t Y2 = hist4->GetYaxis()->GetXmax();

   TPad *null=new TPad("null","null",0,0,1,1);

   null->SetFillStyle(0);
   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();
   auto mark = new TMarker(0,1.5,20);
   mark->Draw();
}

Thanks I will try that soon
Georg

Hi @StephanH, @StephanH , @Dilicus,

I’m still facing a problem with the first mentioned issue:

int test2() {
	TFile *out = new TFile("out.root","RECREATE");
	TCanvas *c1 = new TCanvas();
	TGraph2D *gr2 = new TGraph2D();
	gr2->AddPoint(0,0,3);
	gr2->AddPoint(0,5,4);
	gr2->AddPoint(5,0,5);
	gr2->AddPoint(5,5,5);
	TH2I *h2 = new TH2I("h2","h2",10,0,10,10,0,10);
	gr2->SetHistogram(h2);
	h2->Draw();
	gr2->Draw("cont4z same");
	c1->Write();
	return 0;
}

This code runs, but when I’m opening the root-file and opening the Canvas in the TBrowser it crashes.

Addendum:

Adding something like

gr2->SetName("mygraph");
gr2->Write();

helps to avoid the crash, but the original canvas is not probably saved (only the histo is drawn)
Georg

It does not seems to be related to graphics because if I execute the following macro:

{
   auto out = new TFile("out.root","RECREATE");
   auto gr2 = new TGraph2D();
   gr2->SetName("mygraph");
   gr2->AddPoint(0,0,3);
   gr2->AddPoint(0,5,4);
   gr2->AddPoint(5,0,5);
   gr2->AddPoint(5,5,5);
   auto h2 = new TH2F("h2","h2",10,0,10,10,0,10);
   gr2->SetHistogram(h2);
   gr2->Write();
}

and then do:

$ root out.root
root [1] mygraph->GetHistogram()

 *** Break *** segmentation violation

I also get a crash.

The issue and solution (workaround?) are documented in TGraph2D::SetHistogram(). Save the graph and histo separately in the TFile, then read them and do again gr->SetHistogram(histo).

Hi @couet, Hi @dastudillo,

But this workaround means, that I cannot save TGraph2D piled on TH2 as a part of a TCanvas in a TFile, right?
I can save them separately, and reconstruct the pile manually.

For me this sounds like a bug

I’m frequently using this “save to file” when I’m creating many many graphs or histograms, as the its much simpler to navigate through the charts in the TBrowser than to look for the right Canvas. Beside this, writing to TFile is much much faster

Anyhow the Graph on Histo-pile is not working very well for me I had several cases in the last days were it didn’t work. I’m trying to find out why. For the moment it seems that only the content of the TGraph differs. In some cases it worked, in some only the histo is shown and in some the Tgraph is shown but using the binning of the Histo… I’m confused, I’m trying to figure out more

Georg