Reverse log axis in TH2F

Please provide the following information:


ROOT Version : 6.12/02
Platform : CentOS 7.3 on lxplus7
compiler : gcc6.2


Dear co-rooters,

I am trying to invert the y-axis on a TH2F and at the same time to set it to log.
To do that I have the following macro

#include "TROOT.h"
#include "TH2.h"
#include "TMath.h"
#include "TRandom.h"
#include "TString.h"
#include "TRandom.h"
#include "TGaxis.h"
#include "TPad.h"
#include "TCanvas.h"

void ReverseYAxis (TH2 *h, bool logAxis)
{
   // Remove the current axis
   h->GetYaxis()->SetLabelOffset(999);
   h->GetYaxis()->SetTickLength(0);

   // Redraw the new axis
   gPad->Update();
   TGaxis *newaxis = new TGaxis(gPad->GetUxmin(),
                                gPad->GetUymax(),
                                gPad->GetUxmin()-0.001,
                                gPad->GetUymin(),
                                h->GetYaxis()->GetXmin(),
                                h->GetYaxis()->GetXmax(),
                                510,"+");
   //newaxis->SetLabelOffset(-0.03);
   if (logAxis)
   		gPad->SetLogy(1);
   newaxis->Draw();
}

void test ()
{
   TH2F *hpxpy  = new TH2F("hpxpy","py vs px",40,-4,4,400,1,1000);
   Float_t px, py;
   TRandom r;
   for (Int_t i = 0; i < 25000; i++) {
      r.Rannor(px,py);
      hpxpy->Fill(px,py);
   }
   TCanvas *c1 = new TCanvas("c1");
   hpxpy->Draw("colz");

   ReverseYAxis(hpxpy, 1);
}

The problem is that although the axis is set to log and is indeed inverted, the axis labels are not in logarithmic.
Any idea why and how to solve it?

A sample output id the following

https://imgur.com/8smTli4

You need to add the option “G” in the TGaxis option.

Thank you very much for your reply!
The thing is that I don’t necessarily need to always have logarithmic axis, that is why I used a boolean variable.

Yes but the TGaxis class is the painter for axis. it works via the option only.
Keep the boolean an make and change the string option accordingly .

I changed the function to

void ReverseYAxis (TH2 *h, bool logAxis)
{
   // Remove the current axis
   h->GetYaxis()->SetLabelOffset(999);
   h->GetYaxis()->SetTickLength(0);

	TString draw_option;
	if (logAxis)  draw_option = "G";
	else          draw_option = "+";
	
   // Redraw the new axis
   gPad->Update();
   TGaxis *newaxis = new TGaxis(gPad->GetUxmin(),
                                gPad->GetUymax(),
                                gPad->GetUxmin()-0.001,
                                gPad->GetUymin(),
                                h->GetYaxis()->GetXmin(),
                                h->GetYaxis()->GetXmax(),
                                510, draw_option);
   newaxis->SetLabelOffset(-0.03);
   newaxis->Draw();
}

and I am calling it via

ReverseYAxis(histo, 1);

but the axis doesn’t seem to change…

Any idea?

Seems ok for me:

$ root
   -------------------------------------------------------------------
  | Welcome to ROOT 6.13/03                       http://root.cern.ch |
  |                                      (c) 1995-2017, The ROOT Team |
  | Built for macosx64                                                |
  | From heads/master@v6-13-02-705-g4a2dbe2795, Apr 26 2018, 10:45:03 |
  | Try '.help', '.demo', '.license', '.credits', '.quit'/'.q'        |
   -------------------------------------------------------------------

root [0] TH2D *h2 = new TH2D("h2","h2",10, 0.1, 1000, 10, 0.1, 1000)
(TH2D *) 0x7fa31b9ffc00
root [1] h2->Draw()
Info in <TCanvas::MakeDefCanvas>:  created default TCanvas with name c1
root [2] .x ReverseYAxis.C(h2, true);

Hmmm…

The problem is that although the axis is in log the distribution in the Y-axis is not…

https://imgur.com/gWNDnpK

Yes this is purely graphics … just drawing an extra reverse graphical axis will not change the way the distribution is drawn. You will need to make a temporary histogram inverting the distribution and draw that one instead of the original one. I know this is painful but ROOT was originally designed for HEP where axis are most of the time drawn bottom up.

There is a workaround but I am not sure if it’s the most efficient but it works…

void ReverseYAxis (TH2 *h, bool logAxis)
{
   // Remove the current axis
   h->GetYaxis()->SetLabelOffset(999);
   h->GetYaxis()->SetTickLength(0);

	TString draw_option;
	if (logAxis)  draw_option = "G";
	else          draw_option = "+";
	
   // Redraw the new axis
   gPad->Update();
   TGaxis *newaxis = new TGaxis(gPad->GetUxmin(),
                                gPad->GetUymax(),
                                gPad->GetUxmin()-0.001,
                                gPad->GetUymin(),
                                h->GetYaxis()->GetXmin(),
                                h->GetYaxis()->GetXmax(),
                                510, draw_option);
   newaxis->SetLabelOffset(1);
   
   if (logAxis)
   		gPad->SetLogy(1);
   
   newaxis->Draw();
}

Is there a more efficient or elegant way?

No it does not work… Your bin are not invited along the Y axis …

I don’t understand why you are saying that…

To me it seems that it works.

https://imgur.com/ujVKxCH

I did it by adding the following lines

if (logAxis)
    gPad->SetLogy(1);

When you create your histogram the Y axis goes bottom up from ymin to ymax. xmax is on top and ymin on the bottom of the plot. The bins are ordered this way on the Y axis. If you invert the Y axis, the bins should be also inverted (he top left bin should be drawn bottom left and vice versa) otherwise the value you see on the Y axis will not correspond to the correct bin.

In my case I used SetBinContent() to take into account the inverse of the axis since the reverseAxis() function is a graphical inversion, unless there is something that I miss.

So the bin contents are correct and are insensitive to inverting or no the axis.

Am I missing something?

Ah ok … So you do the bin inversion yourself already. It was not clear in the previous posts That’s fine in that case.

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