def saveas(self, *fnames, **kwargs): """Save plot, close canvas and delete the histograms.""" save = kwargs.get('save', True) close = kwargs.get('close', False) outdir = kwargs.get('outdir', "") # output directory tag = kwargs.get('tag', "") # extra tag for output file exts = kwargs.get('ext', []) # [".png"] pdf = kwargs.get('pdf', False) exts = ensurelist(exts) if pdf: exts.append(".pdf") if not fnames: fnames = [self.name + tag] if save: for fname in fnames: fname = os.path.join( outdir, repkey(fname, VAR=self.name, NAME=self.name, TAG=tag)) if exts: for ext in ensurelist(exts): if not ext.startswith('.'): ext = '.' + ext fname = re.sub( r"\.?(png|pdf|jpg|gif|eps|tiff?|cc?|root)?$", ext, fname, re.IGNORECASE) self.canvas.SaveAs(fname) elif not any(fname.lower().endswith('.' + e) for e in [ 'png', 'pdf', 'jpg', 'gif', 'eps', 'tif', 'tiff', 'c', 'root' ]): self.canvas.SaveAs(fname + ".png") else: self.canvas.SaveAs(fname) if close: self.close()
def ls(self, *paths, **kwargs): """List contents of given directory.""" verb = kwargs.get('verb', self.verbosity) dryrun = kwargs.get('dry', False) here = kwargs.get('here', False) lscol = kwargs.get('lscol', self.lscol) filters = ensurelist( kwargs.get('filter', []) ) # inclusive filters with glob pattern, like '*' or '[0-9]' wildcards path = self.expandpath(*paths, here=here) retlist = self.execute("%s %s%s" % (self.lscmd, self.lsurl, path), fatal=False, dry=dryrun, verb=verb) delim = '\r\n' if '\r\n' in retlist else '\n' retlist = retlist.split(delim) if isinstance(lscol, int): retlist = [l.split(' ')[lscol] for l in retlist] if retlist and 'No such file or directory' in retlist[0]: LOG.warning(retlist[0]) retlist = [] elif filters: for file in retlist[:]: if not any(fnmatch(file, f) for f in filters): retlist.remove(file) return retlist
def grouphists(hists,searchterms,name=None,title=None,**kwargs): """Group histograms in a list corresponding to some searchterm, return their sum. E.g. grouphists(hists,['TT','ST'],'Top') grouphists(hists,['WW','WZ','ZZ'],'Diboson')""" verbosity = LOG.getverbosity(kwargs) searchterms = ensurelist(searchterms) replace = kwargs.get('replace', False ) # replace grouped histograms with sum in list close = kwargs.get('close', False ) # close grouped histograms kwargs['verb'] = verbosity-1 matches = gethist(hists,*searchterms,warn=False,**kwargs) if searchterms else hists histsum = None if matches: if title==None: title = matches[0].GetTitle() if name==None else name if name==None: name = matches[0].GetName() histsum = matches[0].Clone(name) histsum.SetTitle(title) for hist in matches[1:]: histsum.Add(hist) LOG.verb("grouphists: Grouping %s into %r"%(quotestrs(h.GetName() for h in matches),name),verbosity,2) if replace: hists.insert(hists.index(matches[0]),histsum) for hist in matches: hists.remove(hist) if close: deletehist(hist) else: LOG.warning("gethist: Did not find a histogram with searchterms %s..."%(quotestrs(searchterms))) return histsum
def setlinestyle(self, hists, **kwargs): """Set the line style for a list of histograms.""" verbosity = LOG.getverbosity(self, kwargs) pair = kwargs.get('pair', False) triple = kwargs.get('triple', False) colors = kwargs.get('color', None) colors = kwargs.get('colors', colors) or self.lcolors style = kwargs.get('style', True) styles = style if islist(style) else None styles = kwargs.get('styles', styles) or self.lstyles width = kwargs.get('width', 2) offset = kwargs.get('offset', 0) mstyle = kwargs.get('mstyle', None) styles = ensurelist(styles) LOG.verb( "Plot.setlinestyle: width=%s, colors=%s, styles=%s" % (width, colors, styles), verbosity, 2) if mstyle == None: mstyle = triple or pair for i, hist in enumerate(hists): hist.SetFillStyle(0) if triple: hist.SetLineColor(colors[(i // 3) % len(colors)]) hist.SetLineStyle(styles[i % 3]) hist.SetMarkerSize(0.6) hist.SetMarkerColor(hist.GetLineColor() + 1) elif pair: hist.SetLineColor(colors[(i // 2) % len(colors)]) hist.SetLineStyle(styles[i % 2]) hist.SetMarkerColor(hist.GetLineColor() + 1) if i % 2 == 1: hist.SetMarkerSize(0.6) else: hist.SetMarkerSize(0.0) else: hist.SetLineColor(colors[i % len(colors)]) hist.SetMarkerSize(0.6) hist.SetMarkerColor(hist.GetLineColor() + 1) if style: if isinstance(style, bool): hist.SetLineStyle(styles[i % len(styles)]) else: hist.SetLineStyle(style) hist.SetLineWidth(width) if triple and i % 3 == 2: hist.SetOption('E1') #hist.SetLineWidth(0) hist.SetLineStyle(kSolid) hist.SetLineColor(hist.GetMarkerColor()) elif not mstyle: hist.SetMarkerSize(0)
def ls(self,*paths,**kwargs): """List contents of given directory.""" verb = kwargs.get('verb',self.verbosity) dryrun = kwargs.get('dry', False) filters = ensurelist(kwargs.get('filter',[ ])) # inclusive filters with glob pattern, like '*' or '[0-9]' wildcards path = self.expandpath(*paths) retlist = self.execute("%s %s%s"%(self.lscmd,self.lsurl,path),fatal=False,dry=dryrun,verb=verb).split('\n') if retlist and 'No such file or directory' in retlist[0]: LOG.warning(retlist[0]) retlist = [ ] elif filters: for file in retlist[:]: if not any(fnmatch(file,f) for f in filters): retlist.remove(file) return retlist
def comparevars(file, variable, processes, systag, **kwargs): """Compare up/down variations of input histograms from ROOT file. file: TFile or TDirectory object variable: Variables object processes: list of strings (name of processes) systag: string of systematic (file must contain up/down variation) e.g. comparevars(file,variable,['ZTT','TTT'],'TES') """ text = kwargs.get('text', None) pname = kwargs.get('pname', "stack.png") tag = kwargs.get('tag', "") groups = kwargs.get('group', []) # e.g. [(['^TT','ST'],'Top')] dname = kwargs.get('dname', None) # directory ('bin') name pname = kwargs.get('save', "plot_$PROC$SYST$TAG.png") # save as image file wname = kwargs.get('write', "plot_$PROC$SYST$TAG") # write to file processes = ensurelist(processes) uptag = systag + "Up" downtag = systag + "Down" tdir = ensureTDirectory(file, dname, cd=True) if dname else file for process in processes: hists = [] skip = False for var in [uptag, "", downtag]: hname = process + var hist = gethist(tdir, hname, fatal=False, warn=False) if not hist: skip = True break hists.append(hist) if skip: LOG.warning( "comparevars: Could not find %r in %s. Skipping shape comparison..." % (hname, tdir.GetPath())) continue plot = Plot(variable, hists) plot.draw(ratio=2, lstyle=1) plot.drawlegend() if text: plot.drawtext(text) if pname: pname_ = repkey(pname, PROC=process, TAG=tag) plot.saveas(pname_, ext=['png']) if wname: wname_ = repkey(wname, PROC=process, TAG=tag) plot.canvas.Write(wname_, TH1.kOverwrite) plot.close()
def writetemplate(templatename,outfilename,sublist=[],rmlist=[],applist=[],**kwargs): """Write file from template.""" sublist = [(re.compile("\$%s(?!\w)"%p),str(v)) for p, v in sublist] with open(templatename,'r') as template: with open(outfilename,'w') as file: for i, line in enumerate(template.readlines()): #linenum = "L%d:"%i if any(r in line for r in rmlist): continue # skip line for regexp, value in sublist: #pattern = '$'+pattern if regexp.search(line): #line = line.replace(pattern,str(value)) line = regexp.sub(value,line) file.write(line) for line in ensurelist(applist): file.write(line+'\n') # append
def getfiles(self,*paths,**kwargs): """Get list of files in a given path. Return list of files with full path name, and if needed, a file URL. Use the 'filter' option to filter the list of file names with some pattern.""" verb = kwargs.get('verb',self.verbosity) fileurl = kwargs.get('url', self.fileurl) filters = ensurelist(kwargs.get('filter',[ ])) # inclusive filters with glob pattern, like '*' or '[0-9]' wildcards path = self.expandpath(*paths) filelist = self.ls(path,**kwargs) if fileurl and path.startswith(self.parent): if not isinstance(fileurl,basestring): fileurl = self.fileurl else: fileurl = "" for i, file in enumerate(filelist): if filters and not any(fnmatch(file,f) for f in filters): continue filelist[i] = fileurl+os.path.join(path,file) return filelist
def match(self,patterns,verb=0): """Match sample name to some (glob) pattern.""" patterns = ensurelist(patterns) sample = self.name.strip('/') match_ = False for pattern in patterns: if isglob(pattern): if fnmatch(sample,pattern+'*'): match_ = True break else: if pattern in sample[:len(pattern)+1]: match_ = True break if verb>=2: if match_: print ">>> Sample.match: '%s' match to '%s'!"%(sample,pattern) else: print ">>> Sample.match: NO '%s' match to '%s'!"%(sample,pattern) return match_
def getTGraphRange(graphs, min=+10e10, max=-10e10, margin=0.0, axis='y'): """Get full y-range of a given TGraph object.""" vmin, vmax = min, max graphs = ensurelist(graphs) if axis == 'y': getUp = lambda g, i: y + graph.GetErrorYhigh(i) getLow = lambda g, i: y - graph.GetErrorYlow(i) else: getUp = lambda g, i: x + graph.GetErrorXhigh(i) getLow = lambda g, i: x - graph.GetErrorXlow(i) for graph in graphs: npoints = graph.GetN() x, y = Double(), Double() for i in xrange(0, npoints): graph.GetPoint(i, x, y) vup = getUp(graph, i) vlow = getLow(graph, i) if vup > vmax: vmax = vup if vlow < vmin: vmin = vlow if margin > 0: range = vmax - vmin vmax += range * margin vmin -= range * margin return (vmax, vmax)
def drawlegend(self, position=None, **kwargs): """Create and draw legend. Legend position can be controlled in several ways drawlegend(position) drawlegend(position=position) where position is a string which can contain the horizontal position, e.g. 'left', 'center', 'right', 'L', 'C', 'R', 'x=0.3', ... where 'x' is the position (between 0 an 1) of the left side in the frame. The position string can also contain the vertical position as e.g. 'top', 'middle', 'bottom', 'T', 'M', 'B', 'y=0.3', ... where 'y' is the position (between 0 an 1) of the top side in the frame. Instead of the strings, the exact legend coordinates can be controlled with the keywords x1, x2, y1 and y2, or, x1, y1, width and height: drawlegend(x1=0.2,width=0.4) drawlegend(x1=0.2,width=0.4,y1=0.9,height=0.4) drawlegend(x1=0.2,x2=0.6,y1=0.9,y2=0.4) These floats are normalized to the axis frame, ignoring the canvas margins: x=0 is the left, x=1 is the right, y=0 is the bottom and y=1 is the top side. Values less than 0, or larger than 1, will put the legend outside the frame. """ #if not ratio: # tsize *= 0.80 # signaltsize *= 0.80 verbosity = LOG.getverbosity(self, kwargs) hists = self.hists errstyle = 'lep' if gStyle.GetErrorX() else 'ep' entries = kwargs.get('entries', []) bands = kwargs.get('band', [self.errband]) # error bands bands = ensurelist(bands, nonzero=True) bandentries = kwargs.get('bandentries', []) title = kwargs.get('header', None) title = kwargs.get('title', title) # legend header/title latex = kwargs.get('latex', True) # automatically format strings as LaTeX style = kwargs.get('style', None) style0 = kwargs.get('style0', None) # style of first histogram errstyle = kwargs.get('errstyle', errstyle) # style for an error point styles = kwargs.get('styles', []) position = kwargs.get('pos', position) # legend position position = kwargs.get('position', position) or self.position option = kwargs.get('option', '') border = kwargs.get('border', False) transparent = kwargs.get('transparent', True) x1_user = kwargs.get('x1', None) # legend left side x2_user = kwargs.get('x2', None) # legend right side y1_user = kwargs.get('y1', None) # legend top side y2_user = kwargs.get('y2', None) # legend bottom side width = kwargs.get('width', -1) # legend width height = kwargs.get('height', -1) # legend height tsize = kwargs.get('tsize', _lsize) # text size twidth = kwargs.get('twidth', None) or 1 # scalefactor for legend width theight = kwargs.get('theight', None) or 1 # scalefactor for legend height texts = kwargs.get('text', []) # extra text below legend ncols = kwargs.get('ncols', self.ncols) or 1 # number of legend columns colsep = kwargs.get('colsep', 0.06) # seperation between legend columns bold = kwargs.get('bold', True) # bold legend header panel = kwargs.get('panel', 1) # panel (top=1, bottom=2) texts = ensurelist(texts, nonzero=True) entries = ensurelist(entries, nonzero=False) bandentries = ensurelist(bandentries, nonzero=True) headerfont = 62 if bold else 42 # CHECK LOG.insist(self.canvas, "Canvas does not exist!") self.canvas.cd(panel) scale = 485. / min(gPad.GetWh() * gPad.GetHNDC(), gPad.GetWw() * gPad.GetWNDC()) tsize *= scale # text size # ENTRIES #if len(bandentries)==len(bands) and len(entries)>len(hists): # for band, bandtitle in zip(band,bandentries): # entries.insert(hists.index(band),bandtitle) while len(entries) < len(hists): entries.append(hists[len(entries)].GetTitle()) while len(bandentries) < len(bands): bandentries.append(bands[len(bandentries)].GetTitle()) hists = hists + bands entries = entries + bandentries if latex: title = maketitle(title) entries = [maketitle(e) for e in entries] texts = [maketitle(t) for t in texts] maxlen = estimatelen([title] + entries + texts) # STYLES if style0: styles[0] = style0 while len(styles) < len(hists): hist = hists[len(styles)] if hist in bands: styles.append('f') elif style != None: styles.append(style) elif hasattr(hist, 'GetFillStyle') and hist.GetFillStyle() > 0: styles.append('f') elif 'E0' in hist.GetOption() or 'E1' in hist.GetOption(): styles.append(errstyle) else: styles.append('lp') # NUMBER of LINES nlines = sum([1 + e.count('\n') for e in entries]) #else: nlines += 0.80 if texts: nlines += sum([1 + t.count('\n') for t in texts]) if ncols > 1: nlines /= float(ncols) if title: nlines += 1 + title.count('\n') # DIMENSIONS if width < 0: width = twidth * max(0.22, min(0.60, 0.036 + 0.016 * maxlen)) if height < 0: height = theight * 1.34 * tsize * nlines if ncols > 1: width *= ncols / (1 - colsep) x2 = 0.90 x1 = x2 - width y1 = 0.92 y2 = y1 - height # POSITION if position == None: position = "" position = position.replace('left', 'L').replace( 'center', 'C').replace('right', 'R').replace( #.lower() 'top', 'T').replace('middle', 'M').replace('bottom', 'B') if not any(c in position for c in 'TMBy'): # set default vertical position += 'T' if not any(c in position for c in 'LCRx'): # set default horizontal position += 'RR' if ncols > 1 else 'R' # if title else 'L' if 'C' in position: if 'R' in position: center = 0.57 elif 'L' in position: center = 0.43 else: center = 0.50 x1 = center - width / 2 x2 = center + width / 2 elif 'LL' in position: x1 = 0.03 x2 = x1 + width elif 'L' in position: x1 = 0.08 x2 = x1 + width elif 'RR' in position: x2 = 0.97 x1 = x2 - width elif 'R' in position: x2 = 0.92 x1 = x2 - width elif 'x=' in position: x1 = float(re.findall(r"x=(\d\.\d+)", position)[0]) x2 = x1 + width if 'M' in position: if 'T' in position: middle = 0.57 elif 'B' in position: middle = 0.43 else: middle = 0.50 y1 = middle - height / 2 y2 = middle + height / 2 elif 'TT' in position: y2 = 0.97 y1 = y2 - height elif 'T' in position: y2 = 0.92 y1 = y2 - height elif 'BB' in position: y1 = 0.03 y2 = y1 + height elif 'B' in position: y1 = 0.08 y2 = y1 + height elif 'y=' in position: y2 = float(re.findall(r"y=(\d\.\d+)", position)[0]) y1 = y2 - height if x1_user != None: x1 = x1_user x2 = x1 + width if x2_user == None else x2_user if y1_user != None: y1 = y1_user y2 = y1 - height if y2_user == None else y2_user L, R = gPad.GetLeftMargin(), gPad.GetRightMargin() T, B = gPad.GetTopMargin(), gPad.GetBottomMargin() X1, X2 = L + (1 - L - R) * x1, L + ( 1 - L - R) * x2 # convert frame to canvas coordinates Y1, Y2 = B + (1 - T - B) * y1, B + ( 1 - T - B) * y2 # convert frame to canvas coordinates legend = TLegend(X1, Y1, X2, Y2) LOG.verb( "Plot.drawlegend: position=%r, height=%.3f, width=%.3f, (x1,y1,x2,y2)=(%.2f,%.2f,%.2f,%.2f), (X1,Y1,X2,Y2)=(%.2f,%.2f,%.2f,%.2f)" % (position, height, width, x1, y1, x2, y2, X1, Y1, X2, Y2), verbosity, 1) # MARGIN if ncols >= 2: margin = 0.090 / width else: margin = 0.044 / width legend.SetMargin(margin) # STYLE if transparent: legend.SetFillStyle(0) # 0 = transparent else: legend.SetFillColor(0) legend.SetBorderSize(border) legend.SetTextSize(tsize) legend.SetTextFont(headerfont) # bold for title if ncols > 1: legend.SetNColumns(ncols) legend.SetColumnSeparation(colsep) # HEADER if title: legend.SetHeader(title) legend.SetTextFont(42) # no bold for entries # ENTRIES if hists: for hist1, entry1, style1 in columnize(zip(hists, entries, styles), ncols): for entry in entry1.split('\n'): legend.AddEntry(hist1, entry, style1) hist1, style1 = 0, '' for line in texts: legend.AddEntry(0, line, '') if verbosity >= 2: print ">>> Plot.drawlegend: title=%r, texts=%s, latex=%s" % ( title, texts, latex) print ">>> Plot.drawlegend: hists=%s" % (hists) print ">>> Plot.drawlegend: entries=%s" % (entries) print ">>> Plot.drawlegend: styles=%s" % (styles) print ">>> Plot.drawlegend: nlines=%s, len(hists)=%s, len(texts)=%s, ncols=%s, margin=%s" % ( nlines, len(hists), len(texts), ncols, margin) legend.Draw(option) self.legends.append(legend) return legend
def draw(self, *args, **kwargs): """Central method of Plot class: make plot with canvas, axis, error, ratio...""" # https://root.cern.ch/doc/master/classTHStack.html # https://root.cern.ch/doc/master/classTHistPainter.html#HP01e verbosity = LOG.getverbosity(self, kwargs) xtitle = (args[0] if args else self.xtitle) or "" ratio = kwargs.get('ratio', self.ratio) # make ratio plot square = kwargs.get('square', False) # square canvas lmargin = kwargs.get('lmargin', 1.) # canvas left margin rmargin = kwargs.get('rmargin', 1.) # canvas righ margin tmargin = kwargs.get('tmargin', 1.) # canvas bottom margin bmargin = kwargs.get('bmargin', 1.) # canvas top margin errbars = kwargs.get('errbars', True) # add error bars to histogram staterr = kwargs.get('staterr', False) # create stat. error band sysvars = kwargs.get('sysvars', []) # create sys. error band from variations errtitle = kwargs.get('errtitle', None) # title for error band norm = kwargs.get('norm', self.norm) # normalize all histograms title = kwargs.get('title', self.title) # title for legend xtitle = kwargs.get('xtitle', xtitle) # x axis title ytitle = kwargs.get( 'ytitle', self.ytitle ) # y axis title (if None, automatically set by Plot.setaxis) rtitle = kwargs.get('rtitle', "Ratio") # y axis title of ratio panel latex = kwargs.get( 'latex', self.latex) # automatically format strings as LaTeX with makelatex xmin = kwargs.get('xmin', self.xmin) xmax = kwargs.get('xmax', self.xmax) ymin = kwargs.get('ymin', self.ymin) ymax = kwargs.get('ymax', self.ymax) rmin = kwargs.get('rmin', self.rmin) or 0.45 # ratio ymin rmax = kwargs.get('rmax', self.rmax) or 1.55 # ratio ymax ratiorange = kwargs.get('rrange', self.ratiorange) # ratio range around 1.0 binlabels = kwargs.get( 'binlabels', self.binlabels) # list of alphanumeric bin labels ytitleoffset = kwargs.get('ytitleoffset', 1.0) xtitleoffset = kwargs.get('xtitleoffset', 1.0) logx = kwargs.get('logx', self.logx) logy = kwargs.get('logy', self.logy) ymargin = kwargs.get( 'ymargin', self.ymargin) # margin between hist maximum and plot's top logyrange = kwargs.get( 'logyrange', self.logyrange) # log(y) range from hist maximum to ymin grid = kwargs.get('grid', True) tsize = kwargs.get('tsize', _tsize) # text size for axis title pair = kwargs.get('pair', False) triple = kwargs.get('triple', False) lcolors = kwargs.get('colors', None) lcolors = kwargs.get('lcolors', lcolors) or self.lcolors # line colors fcolors = kwargs.get('fcolors', None) or self.fcolors # fill colors lstyles = kwargs.get('lstyle', None) lstyles = kwargs.get('lstyles', lstyles) or self.lstyles # line styles lwidth = kwargs.get('lwidth', 2) # line width mstyle = kwargs.get('mstyle', None) # marker style option = kwargs.get('option', 'HIST') # draw option for every histogram options = kwargs.get('options', []) # draw option list per histogram roption = kwargs.get('roption', None) # draw option of ratio plot enderrorsize = kwargs.get('enderrorsize', 2.0) # size of line at end of error bar errorX = kwargs.get('errorX', True) # horizontal error bars dividebins = kwargs.get('dividebins', self.dividebins) lcolors = ensurelist(lcolors) fcolors = ensurelist(fcolors) lstyles = ensurelist(lstyles) self.ratio = ratio self.lcolors = lcolors self.fcolors = fcolors self.lstyles = lstyles if not xmin: xmin = self.xmin if not xmax: xmax = self.xmax hists = self.hists denom = ratio if isinstance(ratio, int) and (ratio != 0) else False denom = max(0, min(len(hists), kwargs.get( 'denom', denom))) # denominator histogram in ratio plot # NORMALIZE if norm: if ytitle == None: ytitle = "A.U." scale = 1.0 if isinstance(norm, bool) else norm normalize(self.hists, scale=scale) # DIVIDE BY BINSIZE if dividebins: for i, oldhist in enumerate(self.hists): newhist = dividebybinsize(oldhist, zero=True, zeroerrs=False) if oldhist != newhist: LOG.verb( "Plot.draw: replace %s -> %s" % (oldhist, newhist), verbosity, 2) self.hists[i] = newhist self.garbage.append(oldhist) #if sysvars: # histlist = sysvars.values() if isinstance(sysvars,dict) else sysvars # for (histup,hist,histdown) in histlist: # dividebybinsize(histup, zero=True,zeroerrs=False) # dividebybinsize(histdown,zero=True,zeroerrs=False) # if hist not in self.hists: # dividebybinsize(hist,zero=True,zeroerrs=False) # DRAW OPTIONS if errbars: option = 'E0 ' + option #E01 if not roption: roption = 'HISTE' if len(options) == 0: options = [option] * len(hists) if staterr: options[0] = 'HIST' # E3' else: while len(options) < len(hists): options.append(options[-1]) #if not self.histsD and staterr and errbars: # i = denominator-1 if denominator>0 else 0 # options[i] = options[i].replace('E0','') gStyle.SetEndErrorSize(enderrorsize) if errorX: gStyle.SetErrorX(0.5) else: gStyle.SetErrorX(0) # CANVAS self.canvas = self.setcanvas(square=square, ratio=ratio, lmargin=lmargin, rmargin=rmargin, tmargin=tmargin, bmargin=bmargin) # DRAW self.canvas.cd(1) #self.frame.Draw('AXIS') # 'AXIS' breaks grid for i, (hist, option1) in enumerate(zip(hists, options)): if triple and i % 3 == 2: option1 = 'E1' option1 += " SAME" hist.Draw(option1) LOG.verb( "Plot.draw: i=%s, hist=%s, option=%r" % (i, hist, option1), verbosity, 2) # STYLE lhists, mhists = [], [] for hist, opt in zip(hists, options): if 'H' in opt: lhists.append(hist) else: mhists.append(hist) self.setlinestyle(lhists, colors=lcolors, styles=lstyles, mstyle=mstyle, width=lwidth, pair=pair, triple=triple) self.setmarkerstyle(*mhists, colors=lcolors) # CMS STYLE if CMSStyle.lumiText: #mainpad = self.canvas.GetPad(1 if ratio else 0) CMSStyle.setCMSLumiStyle(gPad, 0) # ERROR BAND if staterr or sysvars: #seterrorbandstyle(hists[0],fill=False) self.errband = geterrorband(self.hists[0], sysvars=sysvars, color=self.hists[0].GetLineColor(), name=makehistname( "errband", self.name), title=errtitle) self.errband.Draw('E2 SAME') # AXES self.setaxes(self.frame, *hists, xmin=xmin, xmax=xmax, ymin=ymin, ymax=ymax, logy=logy, logx=logx, xtitle=xtitle, ytitle=ytitle, ytitleoffset=ytitleoffset, xtitleoffset=xtitleoffset, binlabels=binlabels, ymargin=ymargin, logyrange=logyrange, main=ratio, grid=grid, latex=latex) # RATIO if ratio: self.canvas.cd(2) self.ratio = Ratio(*hists, errband=self.errband, denom=denom, drawzero=True, option=roption) self.ratio.draw(roption, xmin=xmin, xmax=xmax) self.setaxes(self.ratio, xmin=xmin, xmax=xmax, ymin=rmin, ymax=rmax, logx=logx, binlabels=binlabels, center=True, nydiv=506, rrange=ratiorange, xtitle=xtitle, ytitle=rtitle, xtitleoffset=xtitleoffset, grid=grid, latex=latex) self.canvas.cd(1)
def __init__(self, *args, **kwargs): """ Initialize with list of histograms: Plot(hists) or with a variable (string or Variable object) as well: Plot(variable,hists) """ variable = None hists = None self.verbosity = LOG.getverbosity(kwargs) if len(args)==1 and islist(args[0]): hists = args[0] # list of histograms elif len(args)==2: variable = args[0] # string or Variable hists = ensurelist(args[1]) # list of histograms else: LOG.throw(IOError,"Plot: Wrong input %s"%(args)) if kwargs.get('clone',False): hists = [h.Clone(h.GetName()+"_plot") for h in hists] self.hists = hists self.frame = kwargs.get('frame', None ) frame = self.frame or self.hists[0] if isinstance(variable,Variable): self.variable = variable self.name = kwargs.get('name', variable.filename ) self.xtitle = kwargs.get('xtitle', variable.title ) self.xmin = kwargs.get('xmin', variable.xmin ) self.xmax = kwargs.get('xmax', variable.xmax ) self.ymin = kwargs.get('ymin', variable.ymin ) self.ymax = kwargs.get('ymax', variable.ymax ) self.rmin = kwargs.get('rmin', variable.rmin ) self.rmax = kwargs.get('rmax', variable.rmax ) self.ratiorange = kwargs.get('rrange', variable.ratiorange ) self.binlabels = kwargs.get('binlabels', variable.binlabels ) self.logx = kwargs.get('logx', variable.logx ) self.logy = kwargs.get('logy', variable.logy ) self.ymargin = kwargs.get('ymargin', variable.ymargin ) self.logyrange = kwargs.get('logyrange', variable.logyrange ) self.position = kwargs.get('position', variable.position ) self.ncols = kwargs.get('ncols', variable.ncols ) self.latex = kwargs.get('latex', False ) # already done by Variable.__init__ self.dividebins = kwargs.get('dividebins', variable.dividebins ) # divide each histogram bins by it bin size else: self.variable = variable or frame.GetXaxis().GetTitle() self.name = kwargs.get('name', None ) self.xtitle = kwargs.get('xtitle', self.variable ) self.xmin = kwargs.get('xmin', frame.GetXaxis().GetXmin() ) self.xmax = kwargs.get('xmax', frame.GetXaxis().GetXmax() ) self.ymin = kwargs.get('ymin', None ) self.ymax = kwargs.get('ymax', None ) self.rmin = kwargs.get('rmin', None ) self.rmax = kwargs.get('rmax', None ) self.ratiorange = kwargs.get('rrange', None ) self.binlabels = kwargs.get('binlabels', None ) self.logx = kwargs.get('logx', False ) self.logy = kwargs.get('logy', False ) self.ymargin = kwargs.get('ymargin', None ) self.logyrange = kwargs.get('logyrange', None ) self.position = kwargs.get('position', "" ) self.ncols = kwargs.get('ncols', None ) self.latex = kwargs.get('latex', True ) self.dividebins = kwargs.get('dividebins', frame.GetXaxis().IsVariableBinSize()) self.ytitle = kwargs.get('ytitle', frame.GetYaxis().GetTitle() or None ) self.name = self.name or (self.hists[0].GetName() if self.hists else "noname") self.title = kwargs.get('title', None ) self.errband = None self.ratio = kwargs.get('ratio', False ) self.append = kwargs.get('append', "" ) self.norm = kwargs.get('norm', False ) self.lcolors = kwargs.get('lcolors', _lcolors ) self.fcolors = kwargs.get('fcolors', _fcolors ) self.lstyles = kwargs.get('lstyles', _lstyles ) self.canvas = None self.legends = [ ] self.texts = [ ] # to save TLatex objects made by drawtext self.lines = [ ] self.garbage = [ ]