Changing TGAxis range in different TPads simultaneously

Hello Everyone,

When writing a GUI we have the Signal/Slot mechanism using (perhaps)TCanvas::Connect() to make what the tittle is looking for “Changing TGAxis range in different TPads simultaneously”, but AFAIU to do that I have to write the code in terms of classes. Is there any way to achieve the same goal in a “simple” Macro (without having to write headers and classes)? Just to clarify, I have a TMultigraph in one pad and THStack in another Pad, I want to change the range in both of them if the range in one of them is modified.

Any suggestion would be appreciated,

May be using TExec can help:
https://root.cern/doc/master/classTExec.html

Hi @couet. TExec seems to be a way to achieve what I want. I wrote a function using Lambda expression like this:


Int_t SubMain() {

   // Open ROOT File, create graph...

   auto SetSameAxisRange = []() {
           // Here the code to modify axis
   };

   TExec *exec1 = new TExec("exec1","SetSameAxisRange()");
   graph->GetListOfFunctions()->Add(exec1);

    // Write objects to ROOTFile

}

Int_t main(){
     // some code here
    SubMain(/*Arguments from main objects*/)
    // some other code
}

But when I run the script TExec shows (every time some event occurs on the pad):

use of undeclared identifier 'SetSameAxisRange'

It’s kind of difficult to define a function outside SubMain() because that would imply that I have to make global almost all of the objects defined and used only there.

EDIT1: I also tried just pasting the code in the second argument of exec1 but it keeps saying "use of undeclared identifier 'fhs' where fhs is a THStack object". However I can use the pads in this code even the canvas, then I tried c1->GetPrimitive("fhs") but it returns 0.

EDIT2: Regarding EDIT1, THStack is returned by another function (not created by the main code) however if I use the same name that is used in the other function (that I assumed to be independent) it works :frowning:

EDIT3: The following script reproduces what I’m getting:

///////////////////////////////////////////////////////
// $ root -l testexec.C

THStack *GetHS(){
  
  THStack *hs = new THStack("hs","");
  
  TH1F *h1 = new TH1F("h1","test hstack",10,-4,4);
  h1->FillRandom("gaus",20000);
  h1->SetFillColor(kRed);
  hs->Add(h1);
  
  TH1F *h2 = new TH1F("h2","test hstack",10,-4,4);
  h2->FillRandom("gaus",15000);
  h2->SetFillColor(kBlue);
  hs->Add(h2);
  
  TH1F *h3 = new TH1F("h3","test hstack",10,-4,4);
  h3->FillRandom("gaus",10000);
  h3->SetFillColor(kGreen);
  hs->Add(h3);

  return hs;
}


Int_t testexec(){
  
  TCanvas *cs = new TCanvas("cs","cs",10,10,700,900);
  cs->Divide(1,2);
  
  TGraph *g[3];
  Double_t x[10] = {0,1,2,3,4,5,6,7,8,9};
  Double_t y[10] = {1,2,3,4,5,5,4,3,2,1};
  auto mg = new TMultiGraph();
  for (int i=0; i<3; i++) {
    g[i] = new TGraph(10, x, y);
    g[i]->SetMarkerStyle(20);
    g[i]->SetMarkerColor(i+2);
    for (int j=0; j<10; j++) y[j] = y[j]-1;
    mg->Add(g[i]);
  }

  THStack *fhs = GetHS();
 
  cs->cd(1);
  fhs->Draw();
  
  cs->cd(2);
  mg->Draw("APL");

  TExec *exec1 = new TExec("exec1","cout << fhs << endl;");
  mg->GetListOfFunctions()->Add(exec1);

  return 0;

}

Try this:

///////////////////////////////////////////////////////
// $ root -l testexec.C

THStack *fhs;

THStack *GetHS(){

  THStack *hs = new THStack("hs","");

  TH1F *h1 = new TH1F("h1","test hstack",10,-4,4);
  h1->FillRandom("gaus",20000);
  h1->SetFillColor(kRed);
  hs->Add(h1);

  TH1F *h2 = new TH1F("h2","test hstack",10,-4,4);
  h2->FillRandom("gaus",15000);
  h2->SetFillColor(kBlue);
  hs->Add(h2);

  TH1F *h3 = new TH1F("h3","test hstack",10,-4,4);
  h3->FillRandom("gaus",10000);
  h3->SetFillColor(kGreen);
  hs->Add(h3);

  return hs;
}

void execfhs()
{
cout << fhs << endl;
}

Int_t testexec(){

  TCanvas *cs = new TCanvas("cs","cs",10,10,700,900);
  cs->Divide(1,2);

  TGraph *g[3];
  Double_t x[10] = {0,1,2,3,4,5,6,7,8,9};
  Double_t y[10] = {1,2,3,4,5,5,4,3,2,1};
  auto mg = new TMultiGraph();
  for (int i=0; i<3; i++) {
    g[i] = new TGraph(10, x, y);
    g[i]->SetMarkerStyle(20);
    g[i]->SetMarkerColor(i+2);
    for (int j=0; j<10; j++) y[j] = y[j]-1;
    mg->Add(g[i]);
  }

  fhs = GetHS();

  cs->cd(1);
  fhs->Draw();

  cs->cd(2);
  mg->Draw("APL");

  TExec *exec1 = new TExec("exec1","execfhs();");
  mg->GetListOfFunctions()->Add(exec1);

  return 0;

}

Thanks @couet, I don’t really want to do it that way because that would imply I’d have to make a couple of variables global (which I don’t want). I’ll keep it with the same name as it works that way without making variables global. I got an additional question regarding what I mentioned before about Lambda expressions, it is a CPP feature from C++11. Is there any way to make them work in this context?

The 2nd parameter of TExec in a simple text string. It is not parsed … thats why I suggested this approached

Hi,

Most probably, your lambda expression should be defined as global entity - outside function scope. Otherwise it simply destroyed after function exit.

Regards,
Sergey

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