TMultiGraph->GetXaxis()->SetTitle (version 4.01)

why this:

...
TGraph *a = new TGraph(3,x1,y1);
TGraph *b = new TGraph(3,x2,y2);
TMultiGraph *mg = new TMultiGraph();
mg->Add(a);
mg->Add(b);
mg->Draw("APL");

ok, but:

mg->GetxAxis()->SetTitle("x");Error: illegal pointer to class object axis 0x0 226  

FILE:(tmpfile) LINE:1
*** Interpreter error recovered ***

you need gPad->Update(); before GetXaxis();

why is it so complicated???

I have a function

TMultiGraph* f(.....)
{
  TMultiGraph* mg = new TMultigraph()
   ....
  return mg
}

that doesn’t know who is gPad! If the axis is a member of TMultiGraph why I have to invoce a method that is not inside TMultiGraph?

the axis are created only when the graph in plotted.

I’ve run into this again recently and am a bit frustrated with the behavior. How can someone write a routine that returns a TMultiGraph to the user without plotting it? Why does TGraph allow the axis titles to be set without a call to gPad->Update()? (I’m using ROOT 6.11.02 here.)

This problem has come up a number of times in the past and I think that it is disconcerting that the behavior is different than TGraph. At some point in the past this same issue also came up with TGraph2D and it was suggested that this behavior is a bug and should be corrected:

A few of the previous complaints about TMultiGraph:

An example:

TMultiGraph* MakeGraph(bool verbose = true) {
   const int numPoints = 3;
   float x[numPoints] = {5, 8, 9};
   float y1s[numPoints] = {10, 13, 8};
   float y2s[numPoints] = {11, 12, 7};
   TGraph *g1 = new TGraph(3, x, y1s);
   TGraph *g2 = new TGraph(3, x, y2s);
   g2->SetLineColor(kRed);
   g2->SetMarkerColor(kRed);

   TMultiGraph *mg = new TMultiGraph();
   mg->Add(g1);
   mg->Add(g2);

   g1->GetXaxis()->SetTitle("X-axis");
   g2->GetYaxis()->SetTitle("Y-axis");

   //Guess we have to check if the Axis (Histogram) is defined.
   if (mg->GetXaxis() && mg->GetYaxis()) {
      mg->GetXaxis()->SetTitle("X-axis");
      mg->GetYaxis()->SetTitle("Y-axis");
   }

   if (verbose) {
      printf("TGraph: %p TMultiGraph %p\n", g1->GetHistogram(), mg->GetHistogram());
   }

   return mg;
}

void multigraph_example() {

   TMultiGraph *mg = MakeGraph();

   //Ahhh it crashes! Would not have expected to have to check for nulls from every method.
   std::cout << "X-axis label: " << mg->GetXaxis()->GetTitle() << "\n";
}

(11 years later! :cry:)

Thanks to reactivate this 11 years old post. I will check what can be done for TMultiGraph

2 Likes

Just a reminder.
You can set all axes titles “in advance”, without the need to create the embedded histogram (which then provides the real axes when drawing):
mg->SetTitle(“Global Multi-Graph Title;X Axis Title;Y Axis Title;Z Axis Title”);
Note that if you want to “skip” any title, simply use a free “;” in its place.

1 Like

Yes that’s an other way. May be in @ksmith case that’s not possible. I have made a PR which allows to do:

root [0] TGraph g; g.SetPoint(0,1,1);g.SetPoint(1,2,1);TMultiGraph mg;mg.Add(&g);
root [1] mg.GetXaxis()->SetTitle("aaa");

Do you still find it useful ?

Ah yes, I am aware of this. I assumed that it would not work either, but did not test it. Thanks for the suggestion. Alas, it still does not solve the case where one tries to get the X-axis title before drawing the multigraph as in the example I provided above.

I would find this to be a very useful, in my opinion it should work the same as the other TGraph classes.

I have committed the PR

1 Like

Works perfectly for the example I posted. Thanks.

1 Like

@couet in the release note, you wrote that this feature will be part of ROOT 6.12. Yet, as far as I understand, you only commited the code in the master branch, not in the v12-patches branch.

TMultiGraph was misspelled as well.

Your are both right. It is fixed. Thanks :slight_smile: