9 """Helpers for drawing ROOT objects.
10 The main function in here is draw_obj(obj [, options]).
11 This is similar to obj->Draw(options), but some extra
12 functionality is added:
14 - Automatic zone handling. You can split the canvas into
15 subpads (zones) with zone(). Each call to draw_obj() will
16 plot into the next sequential pad (unless SAME was specified).
17 Selecting a pad by clicking with button 2 will change
18 the sequence so that the next objects is drawn in the
19 selected pad. draw_obj also takes an optional padnum
20 argument to explicitly specify the pad number to use.
22 - If the SAME option is given, then the new object will be
23 superimposed on an existing one in the current pad.
24 In the case of 1D histograms, we change the line
25 type of the new histogram, and also rescale the vertical
26 axis, if needed to make the new histogram fit.
28 - The option MERGE is like SAME, except that we step through
29 the pads as normal. The new plot will be made on top of
30 whatever happens to be on that pad. By default, the line
31 type used will be the same as one would get the first time
32 one overlays a plot with SAME; to override this, put a number
33 directly after the option, like `MERGE2'.
35 - The option NORM draws the histogram normalized to 1.
37 - The option LOGY draws the histogram using a logarithmic
38 y-axis, and LOGX draws it with a logarithmic x-axis.
40 - The line type will recycle after four histograms have
41 been superimposed. If the LINECOLORS option is given, then
42 the new histograms will be drawn in a different color.
44 - draw_obj takes optional min and max parameters to set the
45 minimum and maximum values for the y-axis of the histogram
48 Besides draw_obj, a few other functions are available.
49 zone(nx,ny) was already mentioned.
50 printeps(fname) is a shortcut to print an eps file from the current canvas.
51 get_canvas() returns the canvas currently being used for drawing.
52 get_pad() returns the pad currently being used for drawing.
54 from __future__
import division
57 from ROOT
import gROOT, TCanvas, TVirtualPad, TH1, TH2, TObject
76 """Helper class for parsing options."""
89 options = options.replace (
',',
' ')
90 for o
in options.split():
92 if lo
in [
"merge",
"same",
"norm",
"logx",
"logy",
'linecolors']:
104 if lo.startswith (pat+
'='):
105 setattr (self, pat, int (lo[len (pat)+1:]))
110 def draw_obj (obj, options = "", padnum = -1, pad = None, min=None, max=None):
111 """Draw the root object OBJ in the next available pad.
114 obj - The object to draw.
115 options - Drawing options.
116 These are passed through to the root Draw
117 method, except that we have special
118 handling for the SAME option, and add a new MERGE option.
119 See the header for details.
120 padnum - If this is a non-negative integer, then this specifies
121 the pad in which to draw, overriding
122 other specifications except for PAD. Note: subpad numbers
124 pad - Explicitly specify the pad to use for drawing.
125 Overrides all other specifications.
128 The object that we drew (may not be the same as OBJ if we
138 op = _options (options)
147 if op.same
or op.merge:
169 pad = get_pad (advance_p, padnum)
171 if not op.merge
and not op.same:
172 pad.SetLogx (
not not op.logx)
173 pad.SetLogy (
not not op.logy)
175 if isinstance (obj, TH1)
and not isinstance (obj, TH2):
188 if rescale_p
and max
is None:
191 prims = pad.GetListOfPrimitives()
193 prims.ResetBit(TObject.kMustCleanup)
195 if isinstance (obj, TH1):
201 if hfirst
and h.GetMaximum() > hfirst.GetMaximum():
202 hfirst.SetMaximum (h.GetMaximum() * 1.1)
204 if hfirst
and h.GetMinimum() < hfirst.GetMinimum():
205 hfirst.SetMinimum (h.GetMinimum())
209 hh = h.DrawCopy (op.other)
211 hh.SetLineStyle (op.linetype)
213 hh.SetLineStyle ((_samecount%4)+1)
215 hh.SetLineColor (op.color)
216 elif op.linecolors
and _samecount >= 4:
217 hh.SetLineColor (_samecount//4 + 1)
219 hh.SetFillColor (op.fill)
229 """Advance to the next pad, if requested.
230 Allow clicking on the pads (button 2) to change the next pad.
232 global _lastpad, _nextpad, _npads
235 pad = TVirtualPad.Pad()
239 pad.GetCanvasID() == c1.GetCanvasID()
and
240 pad.GetNumber() != _lastpad
and pad.GetNumber() != 0):
241 _nextpad = pad.GetNumber()
242 if _nextpad > _npads:
250 if _nextpad > _npads:
262 _nextpad = _lastpad + 1
263 if _nextpad > _npads:
271 return TVirtualPad.Pad()
276 """Return the canvas named CNAME.
277 Create it if it doesn't exist.
280 _canvas = gROOT.FindObject (cname)
282 _canvas = TCanvas (cname, cname, 700, 600)
283 _canvas.SetLeftMargin (0.15)
284 _canvas.SetBottomMargin (0.15)
292 """Divide the canvas into subpads.
293 NX and NY are the number of subpads in x and y, respectively.
295 global _npads, _nextpad, _lastpad
306 """Print the current canvas as an eps file."""
309 c1.Print (s,
"eps,Portrait")