Break axis

hi
does anybody know whether it is possible to break the axis in root, to avoid white space. For example to have a y-axis scale from 10^-20 up to 10^-18, break, 10^-3 up to 1.
thanks for any help
florian

This has been already asked in the past but as not been implemented yet. The problem with this is to define the coordinate system used to draw the data. The way to do it is to draw two pads next to each other but then you have to draw the data in each of them. How to you handle the data ? are they histograms or graphs ? The axis is not the difficult part of this.

Hi
I use TGraph to create the diagrams like attached. The code to get the diagram is the following:

void pcharm(){

  gROOT->SetStyle("Plain");
  gStyle->SetOptStat(0);

//charmed particles
   const int N = 11;
   double x[N] = {1,2,3,4,5,6,7,8,9,10,11};
   double y[N] = {0.175,0.454,0.131,0.1937,0.101,0.0052,0.0023,0.0041,0.0052, 0.0083, 0.078};
   double ey[N] = {0.016,0.030,0.021,0.0057,0.048,0.0004,0.0004,0.0011,0.0011,0.0031,0.017};
   double ex[N] = {0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2,0.2};

   double BSQ[N] = {9.0588e-06,2.228e-05,4.187e-06,8.743e-06,2.423e-06,3.237e-06,1.0573e-07,2.8767e-07,3.6016e-07,3.1789e-07,2.5e-06};
   double BSQ2[N] = {0.1472,0.4673,0.14565,0.1487,0.07876,0.00590487,0.001706,0.00497612,3.0619e-03,2.7586e-03,0.082798};
   const char* labels[N] = {
      "D^{#pm}",
      "D^{0}",
      "D_{s}^{#pm}",
      "D*^{#pm}",
      "D_{s}*^{#pm}",
      "J/#psi",
      "#psi'",
      "#chi_{c1}",
      "D^{#pm}_{s1}",
      "D^{#pm}_{s2}",
      "#Lambda^{#pm}_{c}"
   };

/*
   float chi2 = 0;
   for(int i = 0; i < N; i++){
         chi2 += ((y[i]-BSQ2[i])*(y[i]-BSQ2[i]))/(ey[i]*ey[i]);
   }
   cout<<"chi2 = "<<chi2<< endl;
*/

   TCanvas *c1 = new TCanvas("c1","yields",100,100,1200,1000);
   c1->SetLogy();

   c1->SetGridx();
   TGraphErrors *gr = new TGraphErrors(N,x,y,0,ey);  //y-errors noch reinmachen
   TGraphErrors *gr2 = new TGraphErrors(N,x,BSQ,ex,0);
   TGraphErrors *gr3 = new TGraphErrors(N,x,BSQ2,ex,0);

   gr->SetMarkerStyle(22);
   gr->SetMarkerColor(4);
   gr->SetMarkerSize(1.4);
   gr->GetXaxis()->SetNdivisions(520);
   gr2->SetLineWidth(3);
   gr3->SetLineWidth(3);
   gr3->SetLineColor(2);
   gr3->SetMarkerSize(0);
   gr3->SetMarkerColor(2);
   gr->SetLineWidth(2);

   gStyle->SetErrorX(100);

   gr->SetMaximum(2);
   gr->SetMinimum(4e-8);

   TMultiGraph* mg = new TMultiGraph();
   mg->Add(gr,"AP");
   mg->Add(gr2,"ZP");
   mg->Add(gr3,"ZP");
   mg->Draw("p");

   gr->GetYaxis()->SetTitle("multiplicities");
   gr->GetYaxis()->SetTitleOffset(1.1);
   gr->GetXaxis()->SetTitle("");
   gr->GetXaxis()->CenterTitle();
   gr->GetXaxis()->SetTickLength(0);
   gr->GetXaxis()->SetTitleOffset(0.6);
   gr->GetXaxis()->SetLabelSize(0);
   gr->GetYaxis()->SetLabelSize(0.037);
   gr->SetTitle("");
   gr->GetHistogram()->SetAxisRange(0,11.5,"X");

   TLatex l;
   l.SetTextSize(0.026);
   l.SetTextAngle(90);
   l.SetTextAlign(12);

   for (int i = 0; i < N; i++){
      l.DrawLatex(x[i],1.5e-8,labels[i]);
   }
/*
   TText *t1 = new TText(0.8,5e-5,Form("chi2/dof = %.2f/4",chi2)); 
   t1->SetTextSize(0.03); 
*/
   leg = new TLegend(0.55,0.79,0.99,0.9);
   leg->AddEntry(gr,"LEP data (91 GeV)","p");
   leg->AddEntry(gr2,"uncorrelated jet scheme","l");
   leg->AddEntry(gr3,"correlated jet scheme","l");
   leg->SetTextSize(0.02);
   leg->SetBorderSize(0);
   leg->SetFillStyle(0);
   leg->Draw();
}

I would like to break the axis to get rid of about three orders of magnitude…
thanks for help and best regards
florian


It looks like you have two graphs each of them being in a different region. The best is to draw to pads next to each other.

Example:

void BrokenAxis() 
{
   TCanvas *c = new TCanvas("c", "c",700,900);          

   TPad *p1 = new TPad("p1","p1",0.1,0.5,0.9,0.901); 
   p1->SetBottomMargin(0.);            
   p1->SetBorderMode(0);
   p1->Draw();

   TPad *p2 = new TPad("p2","p2",0.1,0.1,0.9,0.501);
   p2->SetTopMargin(0.);   
   p2->SetBorderMode(0);
   p2->Draw();

   float x1[] = {3,5,6,9}; float y1[] = {100,900,400,200};
   TGraph *gr1 = new TGraph(4,x1,y1);
   gr1->GetXaxis()->SetLimits(0.,10.);                       
   gr1->SetTitle("");
   gr1->GetXaxis()->SetLabelSize(0);
   gr1->GetXaxis()->SetTickLength(0);   
   gr1->SetMarkerStyle(20);

   float x2[] = {1,2,3,8}; float y2[] = {4,7,6,5};
   TGraph *gr2 = new TGraph(4,x2,y2);
   gr2->GetXaxis()->SetLimits(0.,10.);      
   gr2->SetTitle("");
   gr2->SetMarkerStyle(22);

   p1->cd();
   gr1->Draw("ALP");
   gr1->GetHistogram()->SetMinimum(-20.);        
   
   p2->cd();
   gr2->Draw("ALP");
   gr2->GetHistogram()->SetMaximum(7.5);  

   c->cd();
   TPad *b = new TPad("b","b",0.1,0.46,0.8199,0.54);
   b->SetBorderMode(0);
   b->Draw();
   b->cd();
   TLine *line = new TLine(0.11,0,0.1105677,0.399656);
   line->Draw();
   line = new TLine(0.1105677,0.5860092,0.11,1);
   line->Draw();
   line = new TLine(0.076639,0.5143349,0.1524797,0.6863532);
   line->Draw();
   line = new TLine(0.076639,0.3423165,0.1524797,0.5143349);
   line->Draw();
}


thanks a lot… this is exactly what I need
regards
florian

Hello, everyone, there is a feasible way to beak X (or Y) axis on both sides. Here, both sides mean the symmetry?

Can you post a sketch showing what you are looking for ?

1 Like

Hello, I think that the question (in which I am now interested) was how to put a break on both sides of the Y axis, i.e. the left and right axis, like in the sketch I attach.
I think the solution is to draw another pad, but I am fighting with the positioning of the pad…could you please provide a macro? Or maybe suggest a clever way to set the pad position…I am doing some trials but it is taking me forever.

(Also, if I run the macro from July 2008 in this conversation, the pad is shifted with respect to the attached plot…I am guessing due to the many root versions which have changed over the years, but I was wondering if that is a specific reason. I am using root 6.24/06)

Welcome to the ROOT forum.
Can you post the example you made ? BrokenAxis.C works for me.

Thank you very much for the quick reply.
I am using BrokenAxis.C (with other data but the core is the same, just some style changes) and I have discovered that it is Atlas Style which shifts the pad to the left (no idea why but I have to use it and cannot really look into it. It affects the canvas border somehow, but I do not think it is useful to look into that in this context).
To fix this for my plot I have changed the coordinates of the pad until it matched again my axis.

//the rest of the code is the same as in BrokenAxis.C
double shift = 0.04855;
TPad *b = new TPad("b","b",0.1+shift,0.46,0.8199+shift,0.54);

So, actually the macro works perfectly, sorry about that, but I did not think the style could to affect this.

Even if we ignore that issue (which is specific to my case), I am still having trouble adding the pad on the other side. If I apply a rigid shift to a copy of the TPad b, to bring it to the right Y axis (like I did in the code above), I go outside of the canvas because I cannot manage to reduce the pad size without affecting the dimensions of the lines. I think I have to act on the TLine line coordinates, but I did not manage to do it effectively.
Is there a clever way to handle the lines size and position? How did you find the correct dimensions of the lines?

Thank you very much

Can you provide a reproducer ?