Axis labels overlapped by pad

When drawing two pads near each other, one pad can overlap the axis label of the other, which looks a little sloppy. Is there any way to avoid this? I have attached an example plot. On the left, the ‘0’ on the axis is cut in half. By itself, it doesn’t matter too greatly, but with many of these plots it is annoying!

Are there any workarounds short of opening it up in an EPS or SVG editor?

Cheers,

  • Peter
def MakeDoublePlot(D, det, col = kRed):
    global p, l, c, leg
    c = TCanvas()
    c.Divide(1, 2)

    p = D.Clone("pull")
    p.Add( det, -1 )
    p.Divide( D )
    topSize = 0.7
    bottomSize = 0.3
    bottomOffset = 0

    p1 = c.cd(1)
    p1.SetPad("a","a", 0, 1 - topSize, 1, 1, kWhite, 0, 0)
    p1.SetTopMargin( 0.01 ); p1.SetBottomMargin( 0 ); p1.SetRightMargin( 0.01 )

    det.SetTickLength( 0.01 / topSize )
    det.GetYaxis().SetLabelSize( 0.04 / topSize )

    det.SetStats(0)
    det.SetTitle("")
    D.SetStats(0)
    D.SetTitle("")

    det.Draw("hist")
    D.Draw("same e1x0")

    p2 = c.cd(2)
    p2.SetPad("b","b", 0, bottomOffset, 1, bottomSize, kWhite, 0, 0)
    p2.SetTopMargin( 0 ); p2.SetBottomMargin( 0.3 ); p2.SetRightMargin( 0.01 )

    p.GetXaxis().SetLabelSize(0.04 / bottomSize); p.GetXaxis().SetNdivisions(510);
    p.GetYaxis().SetLabelSize(0.04 / bottomSize); p.GetYaxis().SetNdivisions(205);
    p.GetYaxis().SetTitle("Pull")
    p.GetXaxis().SetTitle( "cos #theta*" )
    p.GetXaxis().SetTitleSize( 0.04 / bottomSize )
    p.GetYaxis().SetTitleSize( 0.04 / bottomSize )
    p.GetYaxis().SetTitleOffset( 0.34 )
    p.GetYaxis().CenterTitle()

    p.SetTickLength( 0.01 / bottomSize )

    p.SetStats(0)
    p.SetTitle("")

    p.Draw("e1x0")
    l = TLine( -1, 0, 1, 0 )
    l.SetLineColor( col )
    l.Draw()
    p.Draw("e1x0 same")

    return c


One possible way is:

{
   TCanvas* c = new TCanvas("c","c",500,500);
   Double_t eps = 0.005;
   TPad* p1 = new TPad("p1","p1",0.1,0.5,0.9,0.9,0); p1->Draw();
   TPad* p2 = new TPad("p1","p1",0.1,0.1,0.9,0.5+eps,0); p2->Draw();
   p1->SetBottomMargin(0);
   p2->SetTopMargin(0);   

   TH1F* h1 = new TH1F("h1","",100,-2.5,2.5);  
   TH1F* h2 = new TH1F("h2","",100,-2.5,2.5);  
   h1->Fill(0,12000.);
   h2->Fill(0,1.5);   
   p1->cd(); h1->Draw(); 
   p2->cd(); h2->Draw();
   c->cd();
}
1 Like

Thanks for the work around.

One problem though. That’s just overlapping one canvas with another more to try and hide the label entirely. This also hides data points near the axis, which is also unacceptable…

Any other ways?

Change the minimum of the histogram plotted on top in order to give you more space to adjust the top of the bottom pad.

Moving the minmum on the histogram just moves the 0 too. Is it really impossible to simultaneously not have the ‘0’ and to have data points that lie near the axis? :confused:

The bottom margin of a Pad (the top one in that case) is set to 0 there is no more room to draw the X axis labels an X title therefore they are clipped and that’s what you want. But also, the first label which very often goes below the X axis, is also partially clipped. If you changed the Y minimum (lower than the real one) your data will go up and you will be able to hide the partially clipped lower Y label without hiding the data points.

Yes. That is what I did, but it is not being clipped. You can see the line in my original code p1.SetTopMargin( 0.01 ); p1.SetBottomMargin( 0 ); p1.SetRightMargin( 0.01 ) where I set the margin to zero. I added an additional line to move the axis down by some fraction, but the zero just moves up with it.

bottomOverlap = your 0.005.

Here is an other way:

void overlapped () 
{
   TCanvas* c = new TCanvas("c","c",500,500);
   TPad* p1 = new TPad("p1","p1",0.1,0.5,0.9,0.9,0); p1->Draw();
   TPad* p2 = new TPad("p1","p1",0.1,0.1,0.9,0.5,0); p2->Draw();    
   p1->SetBottomMargin(0);
   p2->SetTopMargin(0);

   TH1F* h1 = new TH1F("h1","",100,-2.5,2.5);
   TH1F* h2 = new TH1F("h2","",100,-2.5,2.5);
   h1->Fill(0,12000.);
   h1->Fill(-2.,200); 
   h2->Fill(0.,1.5);
   p1->cd(); h1->Draw();
   p2->cd(); h2->Draw();

   eraselabel(p1,h1->GetXaxis()->GetLabelSize()); 

   c->cd();
}
 
void eraselabel(TPad *p,Double_t h)
{
   p->cd();
   pe = new TPad("pe","pe",0,0,p->GetLeftMargin(),h);       
   pe->Draw(); 
   pe->SetFillColor(p->GetFillColor());  
   pe->SetBorderMode(0);
}

Note that, withthe way, you can go use Divide again. This macro gives the following picture:

Still seems a bit hackish, and I have to turn it off or on for different plots depending on whether they have the problem (or I risk transposing the problem to another label which is further up the canvas).

Also, another strange thing I observed was a small black line visible for a pixel below this ‘erase pad’. It seems that sometimes it doesn’t quite completely cover the label. And ROOT won’t let me set a negative position on the pad so that I can get rid of it :frowning:

Thanks for your help, couet.

This exchange illustrates precisely that despite the many excellent options for putting pads and histograms together, that it is not possible to avoid the chopping of axis labels when pads/histograms are precisely aligned. The lasted plot show one have to resort to not showing the 0 on the vertical scale for the top plot.
In the current scheme ones has to introduce a small bottom margin between the two plots to see the labels fully.

On the other hand in the underlying TText that produces labels there are option to right/left top/bottom justify text. If this option/information could be applied to axis labels, the example discussed in this post could be easily solved.

You can change the axis label offset (TAttAxis::SetLabelOffset). This function
is also available interactively with the graphics editor.

Rene

Dear Rene,

The problem with the labels is not their horizontal positioning (which the axis label offset controls) but their vertical positioning. The lowest Y axis label on the top graph can be cut in half by the bottom pad, and likewise the highest Y axis label on the lower graph can be cut in half by the top pad.

The solutions proposed so far have been

a) to enlarge the lowest pad up a bit to clip the number entirely
- This leads to clipping of data, too
i) SetMinimum() on the graph so that the data moves up
- The axis label moves up too, negating enlarging the lowest pad

b) to occlude the number manually by drawing on top of it.

  • This is nasty. The original problem is not always a problem, sometimes the axis label is drawn a bit upwards, in which case manually drawing on top of it will cause the original problem again. So now it is necessary to manually choose for each plot whether they need to be manually clipped or not. When you have many plots, and the problem can happen on the upper or the lower plot, this gets to be a pain.

Regards,

  • Peter

Let me make one more follow-up to the latest comment. The issue is the
bottom alignment in vertical direction for y-axis and left-alignement in horizontal axis. I have a set of base-macros use to generate plots with multiple sub window (n= nxny) . Attached are two examples for a 21 divisions having same y-axis for both (no content only frames positioned on pads) one has the pads completely aligned, and here you loose 'half the 0
for the second label axis. If this ‘o’ text (and the 0.5 1 etc were left aligned they would all be within the pad for that frame (both one and two has a bottom margin to accommodate the axis title). The second display show you can regain good visual effects by introducing a small margin for the second plot.
This surely look good with current root, but sometime it is nice to really have the two plots/pads together indicating they share the same y-axis in this case.

I hope this helps communicating the message that I believe peter is trying to get across.

best regards
Flemming




I’ve been using the technique of drawing a TPad over the offending number, but even this is unsatisfactory without rather a lot of tweaking. In some of the EPS outputs, the TPad overlaps the axis too, creating a gap in the axis itself! yuck. :confused:

  • Peter

Did anybody find a solution for this problem?
Aligning the label upon the tick mark of the y-axis would be probably the most easy and straightforward solution: is there any way to do that?

Maurizio

Several “problems” have been listed in this post. Which one are you referring to ? can you send me a small example macro ? I will look at it.

I want to align the y-axis labels upon the tick marks to avoid the “half 0” label, highlighted by the arrow in the picture.

Maurizio


testPlotRes.c (1.22 KB)

Yes that’s a tricky case. I would recommend to draw a white filled TPad on top of the 0 like in:

   TCanvas *c = new TCanvas("c","c",600,600);
   c->Divide(1,2,0,0);
   TVirtualPad *p;
   p = c->cd(1);
   p->DrawFrame(0.5, 0.,0.9,299.);
   p = c->cd(2);
   p->DrawFrame(0.5, 0.,0.9,299.);
   c->cd();
   b = new TPad("b", "b",0.05201342,0.479021,0.08557047,0.5314685);
   b->SetBorderMode(0);
   b->Draw();

[quote=“couet”]Yes that’s a tricky case. I would recommend to draw a white filled TPad on top of the 0 like in:

TCanvas *c = new TCanvas("c","c",600,600); c->Divide(1,2,0,0); TVirtualPad *p; p = c->cd(1); p->DrawFrame(0.5, 0.,0.9,299.); p = c->cd(2); p->DrawFrame(0.5, 0.,0.9,299.); c->cd(); b = new TPad("b", "b",0.05201342,0.479021,0.08557047,0.5314685); b->SetBorderMode(0); b->Draw(); [/quote]

Running your example doesn’t solve my problem.
Am I wrong?


for me the 0 is erased… (I just tried)…