Style File と Data File を分離した QDP-like な ROOT での作図
単なる遊びです。Style file にデータの表示形式を書き、データ辞退は Data file に書いて ROOT で図を作る簡易スクリプト。
#!/usr/bin/env python # Teruaki Enoto 2012-02-03 from optparse import OptionParser import array import shlex import ROOT stylefile_def = "/Users/enoto/work/program/root/example/PlotXY/stylefile.txt" class PlotXY(): def __init__(self, data_array, stylefile, outputpdf): self.data_array = data_array self.stylefile = stylefile self.outputpdf = outputpdf def show(self): print "data_array = ", self.data_array print "stylefile = ", self.stylefile def init_par(self): ### initialize parameters self.pars = {"Title" : "str", "Xmin" : "float", "Xmax" : "float", "Xtitle" : "str", "Xlog" : "bool", "Ymin" : "float", "Ymax" : "float", "Ytitle" : "str", "Ylog" : "bool", "Format" : "list", "Style" : " list", "Can_X0" : "int", "Can_Y0" : "int", "Can_Xwid" : "int", "Can_Ywid" : "int", "TitleBorderSize" : "int", "TitleAlign" : "int", "TextFont" : "int", "FrameLineWidth" : "int", "EndErrorSize" : "float" } for par in self.pars: exec("self.%s = %s('%s')" % (par, self.pars[par], '0')) def set_style(self): ### open file try: f = open(self.stylefile) except IOError, err: print 'Error: cannot read stylefile (%s):' % (self.stylefile,), err quit() ### get file content lex = shlex.shlex(f,posix=True) lex.whitespace += "=" lex.whitespace_split = True ### read and set parameters while True: s = lex.get_token() if s!=lex.eof: val = lex.get_token() print s, val if s == "Style" or s == "Format": cmd = "self.%s = %s(%s)" % (s, self.pars[s], val) elif s == "Xlog" or s == "Ylog": if val == "True": cmd = "self.%s = %s(%s)" % (s, self.pars[s], True) elif val == "False": cmd = "self.%s = %s(%s)" % (s, self.pars[s], False) else: print "Error:: Xlog/Ylog must be bool (True or False)" else: cmd = "self.%s = %s('%s')" % (s, self.pars[s], val) exec(cmd) elif s==lex.eof: break else: print "Error: unexpected error in reading the parfile." f.close() def read_all(self): self.graph = [] id = 0 for file in self.data_array: if self.Format[id] == 0: x, y = self.read(file) self.graph.append(ROOT.TGraph(len(x), x, y)) elif self.Format[id] == 1: x, y, xe, ye = self.read_err(file) self.graph.append(ROOT.TGraphErrors(len(x), x, y, xe, ye)) elif self.Format[id] == 2: x, y, xeh, xel, yeh, yel = self.read_asymerr(file) self.graph.append(ROOT.TGraphAsymmErrors(len(x), x, y, xeh, xel, yeh, yel)) else: print "Error:: Format error in style file" quit() id += 1 def read(self, file): print "...reading file %s..." % file x = array.array('f') y = array.array('f') for line in open(file): col = line.split() x.append(float(col[0])) y.append(float(col[1])) return x, y def read_err(self, file): print "...reading file %s..." % file x = array.array('f') y = array.array('f') xe = array.array('f') ye = array.array('f') for line in open(file): col = line.split() x.append(float(col[0])) y.append(float(col[1])) xe.append(float(col[2])) ye.append(float(col[3])) return x, y, xe, ye def read_asymerr(self, file): print "...reading file %s..." % file x = array.array('f') y = array.array('f') xeh = array.array('f') xel = array.array('f') yeh = array.array('f') yel = array.array('f') for line in open(file): col = line.split() x.append(float(col[0])) y.append(float(col[1])) xeh.append(float(col[2])) xel.append(float(col[3])) yeh.append(float(col[4])) yel.append(float(col[5])) return x, y, xeh, xel, yeh, yel def plot(self): can = ROOT.TCanvas("c1","A Simple Graph with error bars", self.Can_X0, self.Can_Y0, self.Can_Xwid, self.Can_Ywid) print self.Xlog, self.Ylog can.SetLogx(self.Xlog) can.SetLogy(self.Ylog) # --- Optional Gstyles --- ROOT.gStyle.SetTitleBorderSize(self.TitleBorderSize) ROOT.gStyle.SetTitleAlign(self.TitleAlign) ROOT.gStyle.SetTextFont(self.TextFont) ROOT.gStyle.SetFrameLineWidth(self.FrameLineWidth) ROOT.gStyle.SetEndErrorSize(self.EndErrorSize) id = 0 for graph in self.graph: if id == 0: graph.Draw("AP") else: graph.Draw("P") graph.SetMarkerColor(self.Style[id][0]) graph.SetLineColor(self.Style[id][0]) graph.SetMarkerStyle(self.Style[id][1]) graph.SetMarkerSize(self.Style[id][2]) id += 1 # --- Range & Title Set --- self.graph[0].SetTitle(self.Title) self.graph[0].GetXaxis().SetLimits(self.Xmin, self.Xmax) self.graph[0].GetXaxis().SetTitle(self.Xtitle) self.graph[0].SetMinimum(self.Ymin) self.graph[0].SetMaximum(self.Ymax) self.graph[0].GetYaxis().SetTitle(self.Ytitle) can.Print(self.outputpdf) def run(self): self.show() self.init_par() self.set_style() self.read_all() self.plot() ############################# if __name__=="__main__": ############################# # --- Interface to command line parser = OptionParser() parser.add_option("-s", "--stylefile", dest="stylefile", default=stylefile_def, type="string", action="store", help="style file name") parser.add_option("-o", "--outputpdf", dest="outputpdf", default="out.pdf", type="string", action="store", help="output pdf file name") (opt, arg) = parser.parse_args() # --- run main --- if len(arg) == 0: print "Error:: No input data_array." quit() else: plot = PlotXY(arg, stylefile=opt.stylefile, outputpdf=opt.outputpdf) plot.run() quit()
ほんで、Style file
Title = "Title" Xmin = 0.8 Xmax = 10.0 Xtitle = "Xtitle" Xlog = True Ymin = 0.1 Ymax = 4.0 Ytitle = "Ytitle" Ylog = True #-------- Format file --------- # Format # 0 : xy # 1 : xy with x, y errors # 2 : xy with x, y asimerr # Style [color, marker, size] Format = [2,1] Style = [[2,20,1.1],[3,22,1.1]] #--------- Other Format ---------- Can_X0 = 200 Can_Y0 = 10 Can_Xwid = 580 Can_Ywid = 450 TitleBorderSize = 0 TitleAlign = 13 TextFont = 132 FrameLineWidth = 1 EndErrorSize = 0.8
Data file は
3.0 2.0 0.2 0.4 0.2 0.1 5.0 2.0 0.1 0.8 0.1 0.2 3.4 2.5 0.1 0.7 0.2 0.1 5.6 0.3 0.1 0.8 0.3 0.2
で、図