def plot(sampleset, channel, parallel=True, tag="", outdir="plots", histdir="", era=""): """Test plotting of SampleSet class for data/MC comparison.""" LOG.header("plot") # SELECTIONS inclusive = "(q_1*q_2<0)" inclusive = inclusive.replace(" ", "") inclusive_cr_qcd = inclusive.replace( "q_1*q_2<0", "q_1*q_2>0" ) # inverting the opposite-sign requirement of the mutau pair into a same-sign requirment selections = [ Sel('inclusive', inclusive), Sel('inclusive_cr_qcd', inclusive_cr_qcd), ] # VARIABLES # TODO section 5: extend with other variables, which are available in the flat n-tuples variables = [ Var('m_vis', 40, 0, 200), ] # PLOT and HIST outdir = ensuredir(repkey(outdir, CHANNEL=channel, ERA=era)) histdir = ensuredir(repkey(histdir, CHANNEL=channel, ERA=era)) outhists = R.TFile.Open(histdir, 'recreate') exts = ['png', 'pdf'] for selection in selections: outhists.mkdir(selection.filename) stacks = sampleset.getstack( variables, selection, method='QCD_OSSS', scale=1.1, parallel=parallel ) # the 'scale' keyword argument - chosen as 1.1 for mutau - # is an extrapolation factor for the QCD shape from the same-sign # to the opposite-sign region fname = "%s/$VAR_%s-%s-%s$TAG" % (outdir, channel, selection.filename, era) text = "%s: %s" % (channel.replace('mu', "#mu").replace( 'tau', "#tau_{h}"), selection.title) for stack, variable in stacks.iteritems(): outhists.cd(selection.filename) for h in stack.hists: h.Write(h.GetName().replace("QCD_", "QCD"), R.TH1.kOverwrite) stack.draw() stack.drawlegend(x1=0.6, x2=0.95, y1=0.35, y2=0.95) stack.drawtext(text) stack.saveas(fname, ext=exts, tag=tag) stack.close() outhists.Close()
def plotSampleSet(channel,sampleset,tag="",outdir="plots"): """Test plotting of SampleSet class for data/MC comparison.""" LOG.header("plotSampleSet") selections = [ 'q_1*q_2<0 && iso_1<0.15 && idDecayModeNewDMs_2 && idDeepTau2017v2p1VSjet_2>=16 && idDeepTau2017v2p1VSe_2>=2 && idDeepTau2017v2p1VSmu_2>=8 && !lepton_vetoes_notau && metfilter', ] variables = [ Var('m_vis', 40, 0, 200), Var('mt_1', "mt(mu,MET)", 40, 0, 200), Var('pt_1', "Muon pt", 40, 0, 120, ), Var('pt_2', "tau_h pt", 40, 0, 120, ), Var('eta_1', "Muon eta", 30, -3, 3, ymargin=1.6, ncols=2), Var('eta_2', "tau_h eta", 30, -3, 3, ymargin=1.6, ncols=2), Var('njets', 8, 0, 8), Var('rawDeepTau2017v2p1VSjet_2', 'rawDeepTau2017v2p1VSjet', 22, 0.78, 1, pos='left'), ] text = "#mu#tau_{h} baseline" if channel=='mutau' else "e#tau_{h} baseline" # PLOT outdir = ensuredir(outdir) parallel = True #and False fname = "%s/plotPico_$VAR%s"%(outdir,tag) for selection in selections: stacks = sampleset.getstack(variables,selection,method='QCD_OSSS',parallel=parallel) for stack, variable in stacks.iteritems(): #position = "" #variable.position or 'topright' stack.draw() stack.drawlegend() #position) stack.drawtext(text) stack.saveas(fname,ext=['png','pdf']) stack.close()
def plotSampleSet(samples, tag="", singlevar=False): """Test SampleSet class: join samples, print out, and plot.""" LOG.header("testSampleSet") # GET HISTS for selection, weight in selections: if singlevar: result = samples.gethists(variables[0], selection, split=False) result.printall() #var, datahist, exphists = result #print var #print datahist #print exphists else: result = samples.gethists(variables, selection, split=False) result.printall() # PLOT outdir = ensuredir("plots") fname = "%s/testSamplesSet_$VAR%s.png" % (outdir, tag) for selection, weight in selections: if singlevar: stack = samples.getstack(variables[0], selection, split=False) stack.draw() stack.drawlegend(position=position) stack.saveas(fname) #tag="_SampleSet",outdir=outdir) stack.close() else: stacks = samples.getstack(variables, selection, split=False) for stack in stacks: stack.draw() stack.drawlegend(position=position) stack.saveas(fname) #tag="_SampleSet",outdir=outdir) stack.close()
def plotsamples(datasample, expsamples, tag=""): """Test Sample.gethist method and plot data/MC comparison.""" LOG.header("plotsamples") # SETTING outdir = ensuredir("plots") fname = "%s/testSamples_$VAR%s.png" % (outdir, tag) # MAKE 1D HISTS for selection, weight in selections: histdict = {} for sample in [datasample] + expsamples: hists = sample.gethist(variables, selection) histdict[sample] = hists print ">>> %r: %s" % (sample.name, [repr(h.GetName()) for h in hists]) # PLOT for i, variable in enumerate(variables): #LOG.header(variable) datahist = histdict[datasample][i] exphists = [histdict[s][i] for s in expsamples] plot = Stack(variable, datahist, exphists) plot.draw(ratio=True) plot.drawlegend(position=position) plot.drawtext(text) plot.saveas(fname) plot.close()
def main(args): LOG.header("Prepare samples") sampleset = [ ('ZTT', "Z -> #tau_{mu}#tau_{h}", 1.00), ('WJ', "W + jets", 0.40), ('QCD', "QCD multijet", 0.30), ('TT', "t#bar{t}", 0.15), ('Data', "Observed", -1 ), ] lumi = 0.001 # [fb-1] to cancel xsec [pb] nevts = args.nevts snames = [n[0] for n in sampleset] scales = {n[0]: n[2] for n in sampleset} # relative contribtions to pseudo data outdir = ensuredir('plots') indir = outdir filedict = makesamples(nevts,sample=snames,scales=scales,outdir=outdir) datasample = None expsamples = [ ] #CMSStyle.setCMSEra(2018) setera(2018,lumi) for name, title, xsec in sampleset: file, tree = filedict[name] fname = file.GetName() color = None #STYLE.getcolor(name,verb=2) data = name.lower()=='data' file.Close() sample = Sample(name,title,fname,xsec,color=color,data=data) #sample = Sample(name,title,fname,xsec,lumi=lumi,color=color,data=data) if sample.isdata: datasample = sample else: expsamples.append(sample) plotsamples(datasample,expsamples) plotsamples2D(datasample,expsamples) testMergedSamples(datasample,expsamples)
def testSampleSet(datasample, expsamples, tag=""): """Test SampleSet class: join samples, print out, and plot.""" LOG.header("testSampleSet") print ">>> Joining samples in one set" % (expsamples) checkMergedSample = True and False singlevar = True and False if checkMergedSample: color = expsamples[0].fillcolor bkgsample = MergedSample('Bkg', "Background", expsamples[1:], color=color) expsamples = [expsamples[0], bkgsample] expsample = MergedSample('Exp', "Expected", expsamples, color=color) expsamples = [expsample] samples = SampleSet(datasample, expsamples) print ">>> samples=%s" % samples print ">>> " samples.printtable() samples.printobjs() print ">>> " # GET HISTS for selection, weight in selections: if singlevar: result = samples.gethists(variables[0], selection) result.printall() #var, datahist, exphists = result #print var #print datahist #print exphists else: result = samples.gethists(variables, selection) result.printall() # PLOT outdir = ensuredir("plots") fname = "%s/testSamplesSet_$VAR%s.png" % (outdir, tag) for selection, weight in selections: if singlevar: stack = samples.getstack(variables[0], selection) stack.draw() stack.drawlegend(position=position) stack.saveas(fname) #tag="_SampleSet",outdir=outdir) stack.close() else: stacks = samples.getstack(variables, selection) for stack in stacks: stack.draw() stack.drawlegend(position=position) stack.saveas(fname) #tag="_SampleSet",outdir=outdir) stack.close()
def checklegend(samples,tag=""): """Check legend entries: colors, titles, ...""" # https://root.cern.ch/doc/master/classTLegend.html LOG.header("checklegend"+tag.replace(' ','')) output = ensuredir('plots') fname = "%s/testStyle_legend%s"%(output,tag) #height = 0.05*(len(samples)) xdim = 550 ydim = 50*(len(samples)+2) #width = 0.4 #x1, y1 = 0.1, 0.9 print ">>> Canvas: %sx%s (nsamples=%d)"%(xdim,ydim,len(samples)) canvas = TCanvas('canvas','canvas',xdim,ydim) #legend = TLegend(x1,y1,x1+width,y1-height) legend = TLegend(0,0,1,1) legend.SetBorderSize(0) legend.SetMargin(0.12) #legend.SetTextSize(tsize) #legend.SetNColumns(ncols) #legend.SetColumnSeparation(colsep) #legend.SetHeader("HTT style",'C') legend.SetTextFont(42) # bold for title hists = [ ] for sample in samples: color = STYLE.getcolor(sample,verb=2) title = STYLE.gettitle(sample,latex=True,verb=2) style = 'ep' if 'Data' in sample else 'f' hist = TH1F(sample,title,1,0,1) hist.SetFillColor(color) #hist.SetLineColor(kBlack) hist.SetLineWidth(2) hist.SetMarkerColor(kBlack) #hist.SetMarkerStyle(1) legend.AddEntry(hist,title,style) if 'Data' in sample: hist.Draw('E1') hists.append(hist) legend.Draw() canvas.SaveAs(fname+".png") canvas.SaveAs(fname+".pdf") canvas.Close()
def main(args): LOG.header("Prepare samples") sampleset = [ ('ZTT', "Z -> #tau_{mu}#tau_{h}", 1.00), ('WJ', "W + jets", 0.40), ('QCD', "QCD multijet", 0.30), ('TT', "t#bar{t}", 0.15), ('Data', "Observed", -1), ] lumi = 0.001 # [fb-1] to cancel xsec [pb] nevts = args.nevts snames = [n[0] for n in sampleset] scales = {n[0]: n[2] for n in sampleset} # relative contribtions to pseudo data outdir = ensuredir('plots') indir = outdir filedict = makesamples(nevts, sample=snames, scales=scales, outdir=outdir) #CMSStyle.setCMSEra(2018) setera(2018, lumi) samples = makeSampleSet(sampleset, filedict) testget(samples) plotSampleSet(samples)
def plot(sampleset, channel, parallel=True, tag="", outdir="plots", histdir="", era=""): """Test plotting of SampleSet class for data/MC comparison.""" LOG.header("plot") # SELECTIONS inclusive = "(q_1*q_2<0)" inclusive = inclusive.replace(" ", "") inclusive_cr_qcd = inclusive.replace( "q_1*q_2<0", "q_1*q_2>0" ) # inverting the opposite-sign requirement of the mutau pair into a same-sign requirment general_cuts = "(pt_1>26.0)&&(pt_2>20.0)&&(eta_1>-2.1)&&(eta_1<2.1)&&(eta_2>-2.3)&&(eta_2<2.3)" selections = [ Sel('kinematic sel.', general_cuts), #Sel('inclusive',inclusive), #Sel('inclusive_cr_qcd',inclusive_cr_qcd), ] # VARIABLES # TODO section 5: extend with other variables, which are available in the flat n-tuples variables = [ Var('m_vis', 40, 0, 200), Var('pt_1', "Muon pt", 40, 0, 120, ctitle={ 'etau': "Electron pt", 'tautau': "Leading tau_h pt", 'emu': "Electron pt" }), Var('pt_2', "tau_h pt", 40, 0, 120, ctitle={ 'tautau': "Subleading tau_h pt", 'emu': "Muon pt" }), Var('eta_1', "Muon eta", 30, -3, 3, ctitle={ 'etau': "Electron eta", 'tautau': "Leading tau_h eta", 'emu': "Electron eta" }, ymargin=1.6, pos='T', ncols=2), Var('eta_2', "tau_h eta", 30, -3, 3, ctitle={ 'etau': "Electron eta", 'tautau': "Subleading tau_h eta", 'emu': "Muon eta" }, ymargin=1.6, pos='T', ncols=2), #Var('m_vis', 40, 0, 200), Var('mt_1', "mt(mu,MET)", 40, 0, 200), #Var("jpt_1", 29, 10, 300, veto=[r"njets\w*==0"]), #Var("jpt_2", 29, 10, 300, veto=[r"njets\w*==0"]), # #Var("jeta_1", 53, -5.4, 5.2, ymargin=1.6,pos='T',ncols=2,veto=[r"njets\w*==0"]), # #Var("jeta_2", 53, -5.4, 5.2, ymargin=1.6,pos='T',ncols=2,veto=[r"njets\w*==0"]), # Var('njets', 8, 0, 8), Var('met', 50, 0, 150), Var('pt_ll', "p_{T}(mutau_h)", 25, 0, 200, ctitle={ 'etau': "p_{T}(etau_h)", 'tautau': "p_{T}(tau_htau_h)", 'emu': "p_{T}(emu)" }), #Var('dR_ll', "DR(mutau_h)", 30, 0, 6.0, ctitle={'etau':"DR(etau_h)",'tautau':"DR(tau_htau_h)",'emu':"DR(emu)"}), #Var('deta_ll', "deta(mutau_h)", 20, 0, 6.0, ctitle={'etau':"deta(etau_h)",'tautau':"deta(tautau)",'emu':"deta(emu)"},logy=True,pos='TRR'), #, ymargin=8, logyrange=2.6 #Var('dzeta', 56, -180, 100, pos='L;y=0.88',units='GeV'), #Var("pzetavis", 50, 0, 200 ), Var('rawDeepTau2017v2p1VSjet_2', "rawDeepTau2017v2p1VSjet", 100, 0.0, 1, ncols=2, pos='L;y=0.85', logy=True, ymargin=2.5), Var('rawDeepTau2017v2p1VSjet_2', "rawDeepTau2017v2p1VSjet", 20, 0.80, 1, fname="$VAR_zoom", ncols=2, pos='L;y=0.85'), Var('rawDeepTau2017v2p1VSe_2', "rawDeepTau2017v2p1VSe", 30, 0.0, 1, fname="$VAR", ncols=2, logy=True, pos='L;y=0.85'), Var('rawDeepTau2017v2p1VSe_2', "rawDeepTau2017v2p1VSe", 30, 0.70, 1, fname="$VAR_zoom", ncols=2, logy=True, pos='L;y=0.85'), # Var('rawDeepTau2017v2p1VSmu_2', "rawDeepTau2017v2p1VSmu", 20, 0.80, 1, fname="$VAR_zoom",ncols=2,logy=True,logyrange=4,pos='L;y=0.85'), # Var('npv', 40, 0, 80 ), ] # PLOT and HIST outdir = ensuredir(repkey(outdir, CHANNEL=channel, ERA=era)) histdir = ensuredir(repkey(histdir, CHANNEL=channel, ERA=era)) outhists = R.TFile.Open(histdir, 'recreate') exts = ['png', 'pdf'] for selection in selections: outhists.mkdir(selection.filename) stacks = sampleset.getstack( variables, selection, method='QCD_OSSS', scale=1.1, parallel=parallel ) # the 'scale' keyword argument - chosen as 1.1 for mutau - # is an extrapolation factor for the QCD shape from the same-sign # to the opposite-sign region fname = "%s/$VAR_%s-%s-%s$TAG" % (outdir, channel, selection.filename, era) text = "%s: %s" % (channel.replace('mu', "#mu").replace( 'tau', "#tau_{h}"), selection.title) for stack, variable in stacks.iteritems(): outhists.cd(selection.filename) for h in stack.hists: h.Write(h.GetName().replace("QCD_", "QCD"), R.TH1.kOverwrite) stack.draw() stack.drawlegend(x1=0.6, x2=0.95, y1=0.35, y2=0.95) stack.drawtext(text) stack.saveas(fname, ext=exts, tag=tag) stack.close() outhists.Close()
def plot(sampleset, channel, parallel=True, tag="", outdir="plots", histdir="", era=""): """Test plotting of SampleSet class for data/MC comparison.""" LOG.header("plot") # SELECTIONS inclusive = "(q_1*q_2<0)" inclusive = inclusive.replace(" ", "") #inclusive_cr_qcd = inclusive.replace("q_1*q_2<0","q_1*q_2>0") # inverting the opposite-sign requirement of the mutau pair into a same-sign requirment zregion = "%s && mt_1_puppimet<60 && nbjets==0 && m_vis>40 && m_vis<100 && dzeta_puppimet>-50 " % ( inclusive) selections = [ Sel('inclusive', inclusive), Sel('zregion', zregion), #Sel('inclusive_cr_qcd',inclusive_cr_qcd), ] # VARIABLES # TODO section 5: extend with other variables, which are available in the flat n-tuples variables = [ Var('m_vis', 40, 0, 200), Var('pt_vis', "p_{T}^{vis} ", 40, 0, 200), Var('pt_Z_puppimet', "p_{T}^{Z} with puppi", 40, 0, 200), #Var('pt_Z_PFmet', "p_{T}^{Z} with PF", 40, 0, 200), #Var('m_2', "m_tau_h", 28, 0.2, 1.6), Var('mt_1_puppimet', "mt(mu,MET) with puppi", 40, 0, 200), #Var('mt_1_PFmet', "mt(mu,MET) with PF", 40, 0, 200), Var('dzeta_puppimet', "D_{zeta} with puppi", 56, -180, 100, pos='L;y=0.88', units='GeV'), #Var('dzeta_PFmet', "D_{zeta} with PF", 56, -180, 100, pos='L;y=0.88',units='GeV'), Var( 'pt_1', "Muon pt", 40, 0, 120, ), Var( 'pt_2', "tau_h pt", 40, 0, 120, ), Var('eta_1', "Muon eta", 30, -3, 3, ymargin=1.6, ncols=2), Var('eta_2', "tau_h eta", 30, -3, 3, ymargin=1.6, ncols=2), Var('njets', 8, 0, 8), Var('nbjets', 8, 0, 8), Var('dR_ll', "DR(mutau_h)", 30, 0, 6.0, ctitle={ 'etau': "DR(etau_h)", 'tautau': "DR(tau_htau_h)", 'emu': "DR(emu)" }), #Var('met_puppimet', "p_{T}^{miss} with puppi", 50, 0, 150), #Var('met_PFmet', "p_{T}^{miss} with PF", 50, 0, 150), Var('rho', "#rho", 40, 0, 80), Var('npv', 40, 0, 80), Var('npv_good', "npv_{good}", 40, 0, 80), Var('id_2', "tau ID vs jet", 65, 0, 65), Var('anti_e_2', "tau ID vs ele", 65, 0, 65), Var('anti_mu_2', "tau ID vs muon", 20, 0, 20), ] # PLOT and HIST outdir = ensuredir(repkey(outdir, CHANNEL=channel, ERA=era)) histdir = ensuredir(repkey(histdir, CHANNEL=channel, ERA=era)) outhists = R.TFile.Open(histdir, 'recreate') exts = ['png'] #exts = ['png','pdf'] for selection in selections: outhists.mkdir(selection.filename) stacks = sampleset.getstack( variables, selection, method='QCD_OSSS', scale=1.1, parallel=parallel ) # the 'scale' keyword argument - chosen as 1.1 for mutau - # is an extrapolation factor for the QCD shape from the same-sign # to the opposite-sign region fname = "%s/$VAR_%s-%s-%s$TAG" % (outdir, channel, selection.filename, era) text = "%s: %s" % (channel.replace('mu', "#mu").replace( 'tau', "#tau_{h}"), selection.title) for stack, variable in stacks.iteritems(): outhists.cd(selection.filename) for h in stack.hists: h.Write(h.GetName().replace("QCD_", "QCD"), R.TH1.kOverwrite) stack.draw() stack.drawlegend(x1=0.6, x2=0.95, y1=0.35, y2=0.95) stack.drawtext(text) stack.saveas(fname, ext=exts, tag=tag) stack.close() outhists.Close()
def plot(sampleset, channel, parallel=True, tag="", outdir="plots", histdir="", era=""): """Test plotting of SampleSet class for data/MC comparison.""" LOG.header("plot") # SELECTIONS inclusive = "(q_1*q_2<0)" inclusive = inclusive.replace(" ", "") # inclusive_cr_qcd = inclusive.replace("q_1*q_2<0","q_1*q_2>0") # inverting the opposite-sign requirement of the mutau pair into a same-sign requirment general_cuts = "(pt_1>26.0)&&(pt_2>20.0)&&(eta_1>-2.1)&&(eta_1<2.1)&&(eta_2>-2.3)&&(eta_2<2.3)" isolation = "(iso_1<0.15)" mt_cut = "(mt<40.0)" mt_pmet_cut = "(mt_pmet<40.0)" topo_cut = "(miss_Pdz-0.85*vis_Pdz>-20)" isdDT = "(iso_2>0.8)" deeptau = "(anti_e_2>=2)&&(anti_mu_2>=8)&&(id_2>=16)" final = general_cuts + "&&" + isolation + "&&" + mt_cut + "&&" + mt_pmet_cut + "&&" + topo_cut + "&&" + deeptau + "&&" + isdDT selections = [ Sel('nominal', inclusive), Sel('kinematic sel.', general_cuts), Sel('isolation', isolation), Sel('mt<40.0', mt_cut), Sel('mtPmet<40.0', mt_pmet_cut), Sel('TopologicalDis', topo_cut), Sel('DeepTau', deeptau), Sel('isoDeepTau', isdDT), Sel('FinalSelection', final), # Sel('inclusive_cr_qcd',inclusive_cr_qcd), ] # VARIABLES # TODO section 5: extend with other variables, which are available in the flat n-tuples variables = [ Var('m_vis', 40, 0, 200), # For nominal cuts # Var('miss_Pdz - 0.85*vis_Pdz', 40, -200, 150), # Var('pt_1', 40, 10, 100), # Var('eta_1', 40, -3, 3), # Var('iso_1', 40, -0.1, 0.5), # # Var('decayMode_1', 30, 0, 30), # # Var('pt_2', 40, 10, 100), # Var('eta_2', 40, -3, 3), # Var('anti_e_2', 40, -10, 10), # Var('anti_mu_2', 40, -10, 10), # Var('iso_2', 40, 0.0, 1.2), # Var('decayMode_2', 30, 0, 30), # # Var('genWeight', 40, -1, 2), # # Var('n_jet',10, 0, 10), # Var('jet1_pt', 40, 10, 100), # Var('jet1_eta',40, -3, 3), # Var('jet2_pt', 40, 10, 100), # Var('jet2_eta', 40, -3, 3), # # Var('n_bjet', 10, 0, 10), # Var('bjet1_pt', 40, 10, 100), # Var('bjet1_eta',40, -3, 3), # Var('bjet2_pt', 40, 10, 100), # Var('bjet2_eta', 40, -3, 3), # # Var('rawMET_phi', 40, -3.5, 3.5), # Var('rawMET_pt', 40, 0, 150), # Var('rawMET_sumEt', 40, 30, 3000), # Var('puppiMET_phi', 40, -3.5, 3.5), # Var('puppiMET_pt', 40, 0, 150), # Var('puppiMET_sumEt', 40, 30, 500), # # Var('vis_Z_pt',40, 0, 200), # Var('real_Z_pt',40, 0, 200), # Var('real_Z_pt_pmet',40, 0, 200), # # Var('dphi',40, -3.5, 3.5), # Var('dphi_pmet',40, -3.5, 3.5), # # Var('mt', 40, 0, 250), # Var('mt_pmet', 40, 0, 250), # # Var('deltaR', 40, 0, 10.0), # Var('puRho', 40, 2, 50), # Var('n_pvert', 50, 0, 50), # Var('n_pileup', 10, 0, 10), ] # PLOT and HIST outdir = ensuredir(repkey(outdir, CHANNEL=channel, ERA=era)) histdir = ensuredir(repkey(histdir, CHANNEL=channel, ERA=era)) outhists = R.TFile.Open(histdir, 'recreate') exts = ['png', 'pdf'] for selection in selections: outhists.mkdir(selection.filename) stacks = sampleset.getstack( variables, selection, method='QCD_OSSS', scale=1.1, parallel=parallel ) # the 'scale' keyword argument - chosen as 1.1 for mutau - # is an extrapolation factor for the QCD shape from the same-sign # to the opposite-sign region fname = "%s/$VAR_%s-%s-%s$TAG" % (outdir, channel, selection.filename, era) text = "%s: %s" % (channel.replace('mu', "#mu").replace( 'tau', "#tau_{h}"), selection.title) for stack, variable in stacks.iteritems(): outhists.cd(selection.filename) for h in stack.hists: print("-----", h.Integral()) h.Write(h.GetName().replace("QCD_", "QCD"), R.TH1.kOverwrite) stack.draw() stack.drawlegend(x1=0.6, x2=0.95, y1=0.35, y2=0.95) stack.drawtext(text) stack.saveas(fname, ext=exts, tag=tag) stack.close() outhists.Close()