# Transform the binning of two completely different histograms so that they match and can be divided

ROOT 6.12/07 ----- pyROOT

Hello,

I have pairs of histograms and each member of the pair has the same number of bins, but with different ranges.
Some times one’s range is completely inside the other, sometimes they overlap a little, and sometimes they do not.

What I want to do is to transform the histograms so that for both, the new range is

``````new_min = min(h1.GetXaxis().GetXmin(), h2.GetXaxis().GetXmin())
new_max = max(h1.GetXaxis().GetXmax(), h2.GetXaxis().GetXmax())
``````

and they have the same number of bins `nbins`.

The reason for this operation is that eventually these histos will be divided.

I have made a function that tries to do that but probably the .SetBins(nbins, new_min, new_max) method is not doing what I think it should. The implementation considers an arbitrary ammount of bins.

``````import ROOT as rt

def same_binning(nbins, *histos):
"""
Make all histos have the same binning and range
"""

# Get the maximum and minimum of x axis of all histos
# Initialize min and max with values that will definately get overwriten
min = 1e50
max = -1e10
for histo in histos:
if (histo.GetXaxis().GetXmin() < min):
min = histo.GetXaxis().GetXmin()
if (histo.GetXaxis().GetXmax() > max):
max = histo.GetXaxis().GetXmax()

# Make all histos have the same binning and range
for histo in histos:
histo.SetBins(nbins, min, max)

# create dummy histos
h1 = rt.TH1F("h1", "h1", 100, 0, 10)
h2 = rt.TH1F("h2", "h2", 100, 1.998, 2.002)

# fill dummy histos with gaussians, exact shape doesn't matter
h1.FillRandom("gaus", 1000)
h2.FillRandom("gaus", 1000)
h2.SetLineColor(rt.kRed)

# plot dummy histos
c = rt.TCanvas("c", "c", 800, 600)
h1.Draw("same")
h2.Draw("same")

c.SaveAs("dummy_histos.png")

# make dummy histos have the same binning
same_binning(100, h1, h2)

# plot dummy histos with same binning
c = rt.TCanvas("c", "c", 800, 600)
h1.Draw("same")
h2.Draw("same")

c.SaveAs("dummy_histos_same_binning.png")
``````

Here is a pyROOT macro that can replicate my problem. What happens is that SetBins(…) changes the bins, but bin “j” has the same entries as it did before.

The expected outcome would be that the small histo would have a very small number (two) of non-zero bins with every other bin having zero entries.

Thank you,
Giorgos

_ROOT Version: 6.12/07
_Platform: linuxx8664gcc
Compiler: Not Provided

This will not work.
You need to create these histograms with the same number of bins and axis limits.

I made it for 2 histograms only. But the best would be to create the histograms directly with the same number of bins and limits.

``````void samebinning() {
// create dummy histos with nb bins
int nb = 100;
auto h1 = new TH1F("h1", "h1", nb, 0, 10);
auto h2 = new TH1F("h2", "h2", nb, 1.998, 2.002);

// fill dummy histos with gaussians, exact shape doesn't matter
h1->FillRandom("gaus", 1000);
h2->FillRandom("gaus", 1000);
h2->SetLineColor(kRed);

// plot dummy histos
auto c = new TCanvas("c", "c", 800, 600);
c->Divide(2,1);
c->cd(1);
h1->Draw();
h2->Draw("same");

double min = TMath::Min(h1->GetXaxis()->GetXmin(), h2->GetXaxis()->GetXmin());
double max = TMath::Max(h1->GetXaxis()->GetXmax(), h2->GetXaxis()->GetXmax());

// Create and fill h2n with the new limits
double h2bw = h2->GetBinWidth(1);
int h2n_nbins = (max-min)/h2bw;
auto h2n = new TH1F("h2n", "h2n", h2n_nbins, min, max);
for (int i=1; i<=nb; i++) {
h2n->Fill(h2->GetBinCenter(i),h2->GetBinContent(i));
}
c->cd(2);
h2n->Draw("hist");
}
``````

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