Need to rescale the x-axis of a TH2

Hi everybody,

I am trying to rescale the x-axis of a TH2. My problem is that I have a TH2 with custom bin sizes and the last bin is very large, 60% of the total width. In this case, this last bin goes from 40-100 (see attached plot).

I would like to rescale the x-axis such that all other bins remain the same (linear scale), but the last bin should shrink to ocupy only ~20% of the total x-width of the plot. The axis should still read “40” at the low edge of the bin and “100” at the high edge. Also, the content of the TH2 should not change.

How do I do this?



Does anybody have an idea here?

Thanks a lot,



what you want is a hacked axis - this is obviously not the way axes were meant to look like :slight_smile: Here you go:

[code]void fakeaxis() {
Double_t binsy[] = {-1., -0.5, -0.1, -0.03, 0., 0.03, 0.1, 0.5, 1.};
Double_t binsx[] = {0., 10., 20., 50., 70., 100., 750.};
const Int_t nBinsx = sizeof(binsx)/sizeof(Double_t) - 1;
const Int_t nBinsy = sizeof(binsy)/sizeof(Double_t) - 1;
TH2* h = new TH2F(“h”, “original”, nBinsx, binsx, nBinsy, binsy);
for (int x = 1; x <= nBinsx; ++x)
for (int y = 1; y <= nBinsy; ++y)
(x + y + 1));
h->Fill(31., 0.11);

TCanvas* c = new TCanvas(“c”, “Fake axis”);

for (int i = 1; i <= nBinsx; ++i) {
h->GetXaxis()->SetBinLabel(i, TString::Format("%g", binsx[i]));

binsx[nBinsx] = 300.;
h->GetXaxis()->Set(nBinsx, binsx);



Cheers, Axel.

Do you want your boxes to have equal size along x but non linear x labels?
if yes, post a file containing your histogram and I will show you how to do it.


Hi Rene,

yes, this is what Karsten and I would like to achieve.
I’ve attached a rootfile containing the specific 2d histograms, e.g. hist_cs.

cross-section.root (12.1 KB)

Hi Dennis,

see a possible example below


void r2d() { TFile *f = TFile::Open("cross-section.root"); TH2 *h1 = (TH2*)f->Get("hist_cs"); Int_t nx = h1->GetXaxis()->GetNbins(); Double_t xmin = h1->GetXaxis()->GetXmin(); Double_t xmax = h1->GetXaxis()->GetXmax(); Int_t ny = h1->GetYaxis()->GetNbins(); Double_t ymin = h1->GetYaxis()->GetXmin(); Double_t ymax = h1->GetYaxis()->GetXmax(); TH2F *h2 = new TH2F("hist_cs_2",h1->GetTitle(),nx,xmin,xmax,ny,ymin,ymax); for (Int_t i=1;i<=nx;i++) { for (Int_t j=1;j<=ny;j++) { h2->SetBinContent(i,j,h1->GetBinContent(i,j)); } } h2->SetEntries(h1->GetEntries()); gStyle->SetPalette(1); TCanvas *c1 = new TCanvas("c1","c1",600,800); c1->Divide(1,2); c1->cd(1); h1->Draw("col"); c1->cd(2); h2->GetXaxis()->SetLabelOffset(999); h2->Draw("col"); TText label; label.SetTextSize(0.04); label.SetTextAlign(22); Double_t ylabel = h2->GetYaxis()->GetBinLowEdge(1) - 0.3*h2->GetYaxis()->GetBinWidth(1); for (Int_t k=0;k<=nx;k++) { Double_t xlow = h1->GetXaxis()->GetBinUpEdge(k); Double_t xnew = h2->GetXaxis()->GetBinLowEdge(k+1); label.DrawText(xnew,ylabel,Form("%5.1f",xlow)); } }

Hi all,

this works for me, the labels are placed where I want them to be (to the edges of the new h2 bins), I am just interested if it was possible to change anyhow the axis markers which make no sense now so that they followed the labels.

Thanks for any suggestions,