Removing only X axis from a histogram?

Hello,

I am trying to create a plot in which two histograms are plotted such that the boxes containing the histograms are exactly adjacent, one above the other sharing the border in between. The histograms have the same horizontal axis, so I’d like to remove the horizontal axis from the top plot only, using just the horizontal axis on the bottom plot. I’d like the vertical axes to appear on both plots. I’ve tried drawing the top histogram with the “ah” option to turn off both axes, but I can’t find a way to redraw the y axis after this.

Another problem is that using Draw with a TStack collection of histograms doesn’t seem to respect the “ah” argument, so that axes are always drawn when I try to use a TStack.

I found that using TCanvas::Divide, if I set the spacing arguments to 0, such as MyCanvas.Divide(1, 2, 0. 0.), the color of the resulting TPads is grey, rather than defaulting to the background color, which I have set to white. Thus I have not been able to make the histogram boxes adjacent while still keeping the desired color.

Any help with either of these issues would be greatly appreciated.
Thanks,
Adrian

To remove the horizontal axis you can do:

   myHisto->GetXaxis()->SetLabelOffset(999);
   myHisto->GetXaxis()->SetLabelSize(0);
1 Like

This approach works for a single histogram, but it doesn’t seem to work for a TStack, even if the GetXaxis()->… commands are applied to the individual histograms before adding to the TStack.

Can you send a small running example showing what you are doing ?

Sure. (I probably should have done so from the start.) This is a simplified version of the function that is giving me problems.

TCanvas* MakePlotOne(TH1F* th_Data, TH1F** th_MC, Int_t i_NMC)
{
  gStyle->SetOptStat(0);

  // clone data histogram for use in second panel of plot
  TH1F* th_Ratio = (TH1F*)th_Data->Clone("th_Ratio");

  // create stack with MC histograms
  THStack* ts_Stack = new THStack();
  for (Int_t i = 0; i < i_NMC; i++) ts_Stack->Add(th_MC[i]);

  TCanvas* tc_Canvas = new TCanvas("tc_Canvas", "Plot 1", 0, 0, 1200, 800);
  tc_Canvas->SetFillColor(kWhite);
  // setting separators to 0 changes color of resulting TPads to grey
  tc_Canvas->Divide(1, 2, 0.0001, 0.0001);

  // generate upper panel of plot
  tc_Canvas->cd(1);

  // try to remove x axis
  th_Data->GetXaxis()->SetTitle("");
  th_Data->GetXaxis()->SetLabelOffset(999);
  th_Data->GetXaxis()->SetLabelSize(0);

  // draw th_Data to set up canvas, then MC histograms from stack
  th_Data->Draw("");
  ts_Stack->Draw("hist, same");
  // redraw th_Data so that its not covered by MC histograms
  th_Data->Draw("same");
 
  // generate lower panel of plot
  tc_Canvas->cd(2);

  // create ratio of data to sum of all MC modes
  for (Int_t i = 0; i < i_NMC; i++) th_Ratio->Add(th_MC[i]);
  th_Ratio->Divide(th_Data);

  // second plot would ideally be exactly beneath first plot
  th_Ratio->SetTitle("");
  th_Ratio->Draw();

  return tc_Canvas;
}

Thanks, but It would be more helpful to have some running example. Your macro has some input parameters which I do not know about. Can you send something I can execute ?

I’m not sure of an easy way to make the necessary histograms in a compilable macro. Instead, I included an eps file showing the kind of plot I’d like to be able to make. Maybe this will be of some use for now? I can continue to work on making some sample histograms to reproduce the problem in an executable script.

Adrian

yes, send the eps. That will help.

I tried to add the plot as an eps file yesterday, but I see now that eps files are not allowed. Here’s a jpeg version instead.


Here is an example showing how to remove the X of a THStack:

{
   THStack *hs = new THStack("hs","test stacked histograms");
   TH1F *h1 = new TH1F("h1","test hstack",100,-4,4);
   h1->FillRandom("gaus",20000);
   h1->SetFillColor(kRed);
   h1->SetMarkerStyle(21);
   h1->SetMarkerColor(kRed);
   hs->Add(h1);
   TH1F *h2 = new TH1F("h2","test hstack",100,-4,4);
   h2->FillRandom("gaus",15000);
   h2->SetFillColor(kBlue);
   h2->SetMarkerStyle(21);
   h2->SetMarkerColor(kBlue);
   hs->Add(h2);
   TH1F *h3 = new TH1F("h3","test hstack",100,-4,4);
   h3->FillRandom("gaus",10000);
   h3->SetFillColor(kGreen);
   h3->SetMarkerStyle(21);
   h3->SetMarkerColor(kGreen);
   hs->Add(h3);
                                                                                
   hs->Draw();
   hs->GetHistogram()->GetXaxis()->SetTickLength(0);
   hs->GetHistogram()->GetXaxis()->SetLabelOffset(999);
}

Thanks. With that command, I was able to remove the labels, and by changing the number of divisions on the axis to 1, I was able to also remove the tick marks. The last task is to create the two separate TPads on which to draw the histograms, but I am again having some trouble here. The problem is that after I create the first pad, the second pad is always defined relative to the first, rather than to the canvas itself. Thus if I try:

TPad* tp_PadTop = new TPad("tp_PadTop", "tp_PadTop", 0.0, 0.2, 1.0, 1.0);
TPad* tp_PadBot = new TPad("tp_PadBot", "tp_PadBot", 0.0, 0.0, 1.0, 0.2);

the bottom TPad appears embedded in the top pad, since the top pad was active when the second pad was defined. I have tried creating a larger pad to hold both smaller pads, but this has so far had no effect:

TPad* tp_PadBig = new TPad("tp_PadBig", "tp_PadBig", 0.0, 0.0, 1.0, 1.0);
tp_PadBig->Draw();
TPad* tp_PadTop = new TPad("tp_PadTop", "tp_PadTop", 0.0, 0.2, 1.0, 1.0);
tp_PadBig->cd();
TPad* tp_PadBot = new TPad("tp_PadBot", "tp_PadBot", 0.0, 0.0, 1.0, 0.2);

The result is the same as if the encompassing pad was not defined.

Basically, I need a way to return to canvas-level coordinates once I’ve created one pad.
Thanks again,
Adrian

first create a TCanvas C and before creating a new pad just do C->cd()

I find that this doesn’t work for me:

TCanvas* tc_Canvas = new TCanvas("tc_Canvas", "Plot 1", 0, 0, 1200, 800);
TPad* tp_PadTop = new TPad("tp_PadTop", "tp_PadTop", 0.0, 0.2, 1.0, 1.0);
tc_Canvas->cd();
TPad* tp_PadBot = new TPad("tp_PadBot", "tp_PadBot", 0.0, 0.0, 1.0, 0.2);

It was my first guess, but I gave up on it when I found it gave the same results with the second TPad embedded in the first. Could it be that there is something wrong with my choice of coordinates?

example:

{
   TCanvas *c1 = new TCanvas("c1", "c1",5,47,700,530);
   c1->Range(0,0,1,1);
   TPad *c1_1 = new TPad("c1_1", "newpad",0.07,0.16,0.47,0.89);
   c1_1->Draw();
   c1->cd();
   c1_2 = new TPad("c1_2", "newpad",0.51,0.17,0.86,0.87);
   c1_2->Draw();
}