Scaling y-axis of two graphs simultaneously


ROOT Version: 6.26/00


How can I get and change the range of the y-axis of a TGraph? I tried finding this in the forum, but none of the posts I found addressed the issue I’m having:

I’m trying to plot two TGraphs on two TPads that are side by side and have the y-axis of the two graphs scale simultaneously (using the AddExec function). I can get this to work easily for the x-axis, but I haven’t been able to get this to work for the y-axis.
If I try and simply use TGraph::GetHistogram()->GetYaxis(), the resulting axis has only one bin (GetFirst() and GetLast() return 1).
If I try and get the TFrame object by looping over the TList from TPad::GetListOfPrimitives(), I get a TFrame from which I can get the right range using TFrame::GetY1() and TFrame:GetY2(). But if I try using that range to change the TFrame of the other TPad, it has no effect (using something like frame2->SetY1(frame1->GetY1());). The values of the TFrame get updated (as evident when using frame2->GetY1() afterwards), but the plotting range does not change, and the next time the same function is called the range of frame2 is back to the old values.
I also tried drawing a TFrame on the TPad and then using TGraph::Draw("*l") instead of TGraph::Draw("a*l"), but that doesn’t change anything (and I can’t easily get the coordinates for the TFrame since TGraph::GetMinimum() and TGraph::GetMaximum() both return the same value of -1111???).

Below is the code of the script I’m using to try and figure this out:

void zoom() {
   TF1* f = new TF1("f", "sin(x)", -10., 10.);
   TGraph* g1 = new TGraph(10);
   TGraph* g2 = new TGraph(100);
   for(Int_t i=0; i<100; ++i) {
      if(i < 10) g1->SetPoint(i, (i-5), f->Eval(i-5));
      g2->SetPoint(i, (i-50)/10., f->Eval((i-50)/10.));
   }
   TCanvas* canvas = new TCanvas("canvas");
   auto pad1 = new TPad("c1","c1", 0.2, 0., 1., 1.);
   pad1->SetNumber(1);
   pad1->Draw();
   pad1->cd();
   //std::cout<<"setting frame "<<g1->GetPointX(0)<<", "<<g1->GetMinimum()<<", "<<g1->GetPointX(g1->GetN()-1)<<", "<<g1->GetMaximum()<<std::endl;
   //auto frame = pad1->DrawFrame(g1->GetPointX(0), g1->GetMinimum(), g1->GetPointX(g1->GetN()-1), g1->GetMaximum());
   //g1->Draw("*l");
   g1->Draw("a*l");
   pad1->AddExec("ex","zoompad()");
   canvas->cd();
   auto pad2 = new TPad("c2","c2", 0., 0., 0.2, 1.);
   pad2->SetNumber(2);
   pad2->Draw();
   pad2->cd();
   //std::cout<<"setting frame "<<g2->GetPointX(0)<<", "<<g2->GetMinimum()<<", "<<g2->GetPointX(g2->GetN()-1)<<", "<<g2->GetMaximum()<<std::endl;
   //frame = pad2->DrawFrame(g2->GetPointX(0), g2->GetMinimum(), g2->GetPointX(g2->GetN()-1), g2->GetMaximum());
   //g2->Draw("*l");
   g2->Draw("a*l");
   pad2->AddExec("ex","zoompad()");
}

void zoompad() {
   // find the histogram in the current canvas
   TGraph* g1 = nullptr;
   TH1* hist1 = nullptr;
   TFrame* frame1 = nullptr;
   for(const auto&& obj : *(gPad->GetListOfPrimitives())) {
      if(obj->InheritsFrom(TGraph::Class())) {
         g1 = static_cast<TGraph*>(obj);
         hist1 = g1->GetHistogram();
      } else if(obj->InheritsFrom(TFrame::Class())) {
         frame1 = static_cast<TFrame*>(obj);
      }
   }
   if(g1 == nullptr || hist1 == nullptr || frame1 == nullptr) {
      std::cout<<"Failed to find histogram for canvas "<<gPad->GetName()<<std::endl;
      return;
   }

   // extract base name and channel from pad name
   std::string padName = gPad->GetName();
   std::string baseName = padName.substr(0,1);
   std::string channelName = padName.substr(1)
   // find the corresponding partner canvas to the selected one
   TCanvas* canvas2 = nullptr;
   std::string newName;
   if(channelName.compare("1") == 0) {
      newName = baseName + "2";
      canvas2 = static_cast<TCanvas*>(gROOT->FindObject(newName.c_str()));
   } else if(channelName.compare("2") == 0) {
      newName = baseName + "1";
      canvas2 = static_cast<TCanvas*>(gROOT->FindObject(newName.c_str()));
   } else {
      std::cout<<"Unknown combination of canvas "<<gPad->GetName()<<" and histogram "<<hist1->GetName()<<std::endl;
      return;
   }
   if(canvas2 == nullptr) {
      std::cout<<"Failed to find partner canvas "<<newName<<std::endl;
      return;
   }
   // find the histogram in the partner canvas
   TGraph* g2 = nullptr;
   TH1* hist2 = nullptr;
   TFrame* frame2 = nullptr;
   for(const auto&& obj : *(canvas2->GetListOfPrimitives())) {
      if(obj->InheritsFrom(TGraph::Class())) {
         g2 = static_cast<TGraph*>(obj);
         hist2 = g2->GetHistogram();
      } else if(obj->InheritsFrom(TFrame::Class())) {
         frame2 = static_cast<TFrame*>(obj);
      }
   }
   if(g2 == nullptr || hist2 == nullptr || frame2 == nullptr) {
      std::cout<<"Failed to find histogram for canvas "<<newName<<std::endl;
      return;
   }

   TAxis* axis1 = hist1->GetYaxis();
   axis1->Print();
   Int_t binmin = axis1->GetFirst();
   Int_t binmax = axis1->GetLast();
   Float_t xmin = axis1->GetBinLowEdge(binmin);
   Float_t xmax = axis1->GetBinLowEdge(binmax);
   TAxis* axis2 = hist2->GetYaxis();
   Int_t newmin = axis2->FindBin(xmin);
   Int_t newmax = axis2->FindBin(xmax);
   std::cout<<"bin "<<binmin<<" - "<<binmax<<", y "<<xmin<<" - "<<xmax<<", min/max "<<g1->GetMinimum()<<" - "<<g1->GetMaximum()<<", frame1 "<<frame1->GetY1()<<" - "<<frame1->GetY2()<<", frame2 "<<frame2->GetY1()<<" - "<<frame2->GetY2()<<std::endl;
   //axis2->SetRange(newmin,newmax);
   //g2->SetMinimum(g1->GetMinimum());
   //g2->SetMaximum(g1->GetMaximum());
   frame2->SetY1(frame1->GetY1());
   frame2->SetY2(frame1->GetY2());
   std::cout<<"frame1 "<<frame1->GetY1()<<" - "<<frame1->GetY2()<<", frame2 "<<frame2->GetY1()<<" - "<<frame2->GetY2()<<std::endl;
   canvas2->Modified();
   canvas2->Update();
}

On the Y axis there is no bin. To change the limits use SetMaximum() and SetMinimum()

I had tried that (I think I found another post saying to use SetMinimum() and SetMaximum()), but I misunderstood which one that was supposed to be.
Using (as I did) TGraph::SetMinimum() and TGraph::SetMaximum() doesn’t work, one needs to use TH1::SetMinimum and TH1::SetMaximum()!
Thanks, this solved the issue!

1 Like

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