Force Y value to 1 for a normalized histogram

Hi everyone,

I would to draw a normalized histogram.

TH1F *multhistot = new TH1F("multhistot","multhistot",11,0,10);
multhistot->DrawNormalized("" ,1)->SetLineWidth(3);
multhistot->DrawNormalized("same" ,1)->SetLineColor(46);

With the data I have, the maximum value for Y axis is set automatically to 0.6.
But I would like to set it manually to 1, because I plot on the same graph other histogram with higher value on Y.

How can I make that ?

Thank you all.


I made what you wrote, but it doesn’t work.

TH1F *multhistot = new TH1F(“multhistot”,“multhistot”,11,0,10);
multhistot->DrawNormalized("" ,1)->SetLineWidth(3);
multhistot->DrawNormalized(“same” ,1)->SetLineColor(46);

Nothing changes.


Yes, when you use DrawNormalized the scale is redefined. You can first draw a frame with the unit you need and then DrawNormalized with the option “same”.

   TH1 *frame = new TH1F("frame","",1000,-4,4);
1 Like


Thank you.


I’ve also been interested in solving this problem for a while. When you draw multiple
histograms on a same canvas and later you want to normalize all the histograms, sometimes
you may have issues when the maximum of the first histogram is the smallest among all
the others, then the top of all other histograms with lower peaks would be chopped off…

It’s a brilliant idea to firstly draw a frame which is empty and manually set the max of y-axis
to 1 or other comfortable values. But the problem is, you have to set the limits MANUALLY,
which could be tedious especially when you want to draw multiple histograms at a time, though
it solves the problem ( by multiple I mean more than 10 histograms ).

Here is what I’ve done to have the histograms automatically adjust themselves.
Suppose I want to draw the first six elements of var1 — var1[ 0 ], var1[ 1 ] … var1[ 5 ]
and the first six of var2 — var2[ 0 ], var2[ 1 ] … var2[ 5 ].
Given three different samples I have, with the links given respectively addr1, addr2 and addr3,
and okay, let’s write it in python for simplicity’s sake.

samples_ = [ 's1', 's2', 's3' ] # call the sample s1, s2 and s3
links_ = { 's1' : "path/to/addr1", 's2' : "path/to/addr2", 's3' : "path/to/addr3" }
input_nm = [] # name of the x-axis
input_lb = [] # lower bound of the x-axis
input_ub = [] # upper bound of the x-axis
input_nbins = [] # bin numbers 

### fill out all the attributes of the histograms
### for var1 series

for i range( 6 ):
	input_nm.append( 'var1[' + str(i) + '];' )
	input_lb.append( 40 )
	input_ub.append( 100 )
	input_nbins.append( 10 )
### then for var2 series

for i in range( 6 ):
	input_nm.append( 'var2[' + str(i) + '];' )
	input_lb.append( -1.0 )
	input_ub.append( 1.0 )
	input_nbins.append( 100 )
### next, let's create a list of histogram dictionaries
### to deal with different samples

hists_ = []

for i in range( len( input_nm ) ):
	hists_.append( {} )

### sample files

f_in_ = {}
for s in samples_:
	for i in range( len( input_nm ) ):
		### set up all the histograms
		hists_[ i ][ s ] = ROOT.TH1F( "hist"+str(i), 
			";"+input_nm[ i ]+"normalized units",
			input_nbins[ i ], input_lb[ i ], input_ub[ i ] )
	### set up all the sample files and the corresponding trees
	f_in_[ s ] = ROOT.TFile( links_[ s ], "READ" )
	f_in_[ s ].cd()
	tr_in = f_in_[ s ].Get( "tree" ) # set up the input tree
	for i in range( tr_in.GetEntries() ):
		tr_in.GetEntry( i )
		for k in range( len( input_nm ) ):
			if k < 6:
				hists_[ k ][ s ].Fill( tr_in.var1[ k ] )
				hists_[ k ][ s ].Fill( tr_in.var2[ k-6 ] )
### okay, we've finished the filling process
### now, let's draw histograms

for s in samples_:
	for k in range( len( input_nm ) ):
		### since we want to draw normalized histogram later on, and
		### each sample may have events in different scale, we want 
		### to find an absolute max just so we could later compare 
		### different samples on the same scale
		int_s1 = hists_[ k ][ 's1' ].Integral()
		int_s2 = hists_[ k ][ 's2' ].Integral()
		int_s3 = hists_[ k ][ 's3' ].Integral()
		max_int_s = max( int_s1, int_s2, int_s3 )
		scl_s1 = max_int_s / int_s1
		scl_s2 = max_int_s / int_s2
		scl_s3 = max_int_s / int_s3
		### a crucial step here, here is how we automatically adjust
		### the y-axis boundaries. Just keep in mind, we also want
		### to give 20-30% whitespace above the highest peak
		hists_[ k ][ s ].SetMaximum( 1.3*max( 
									  scl_s1*hists_[ k ][ 's1' ].GetMaximum(),
									  scl_s2*hists_[ k ][ 's2' ].GetMaximum(),
									  scl_s3*hists_[ k ][ 's3' ].GetMaximum() )  )
		### since now the correct limit of y-axis has been set,
		### we could comfortably draw the normalized histograms
		### without issues of top getting overlapped or chopped off
		hists_[ k ][ s ].DrawNormalized( "samehist" )