I have several histograms that I would like to draw within the same canvas or pad. Hence, I’m using Draw(“same”).
How do I set the Y axis to automatically expand its range whenever I add a histogram, so as to fit all of the present ones? This has to be something very simple (I hope), but I haven’t found a way.
The “same” and “sames” options are really bad at overlaying plots properly. Unfortunately it’s often the first method found when searching for how to do it. The better way is to use a THStack, which by default draws “stacked” histograms. If you draw the THStack with “nostack”, it draws the superimposed histograms properly with autoscaled Y axis.
I agree, but unfortunately it isn’t so simple due to some rather strange design choices in how ROOT associates histograms with axes and pads. Even worse, there are special cases like THStack where you can only alter the axis limits after drawing it and TGraph where you need to add the “A” draw option to explicitly draw the axes (if it’s the first thing being drawn).
Libraries like matplotlib do a much better job here since you are typically handling an axes object directly and plotting things on that axes object. You can set the range of the axes at any time (without special cases like ROOT) and without modifying properties of the things that are being drawn, like in ROOT where you sometimes need to call SetMinimum() or SetMaximum() on the histogram (stack) being drawn to set the y-axis limits…
So in rootpy I have created some utility functions that automatically handle the special cases and can automatically set the x and y-axis limits, even when drawing multiple histograms, stacks and graphs together.
See the new example here:
github.com/rootpy/rootpy/blob/m … overlay.py
And the functions in rootpy.plotting.utils:
github.com/rootpy/rootpy/blob/m … g/utils.py
(specifically draw() and get_limits())
You can just draw() a bunch of things on a pad and it will take care of the special cases when the first thing being drawn is a stack or a graph and then set the axis limits to accommodate all the objects. You can adjust the amount of space above and below and left and right with the ypadding and xpadding arguments, and it handles logarithmic axes.
Each system has its own way to work for good or bad reasons. Once you are use to one (mathplolib) it is difficult to think another way (ROOT). Thanks for your python macro…
Well, I started with only ROOT and became very familiar with how it handled things before trying matplotlib. That said, I still use ROOT for most things and only resort to matplotlib for certain plots.