source: fact/tools/pyscripts/sandbox/kraehenb/fileplotter.py@ 14912

Last change on this file since 14912 was 14409, checked in by kraehenb, 12 years ago
fileplotter.py allows to browse a file, and saves root plots as png/pdf/root file.
File size: 9.9 KB
Line 
1#!/usr/bin/python
2"""Example usage:
3>>> from fileplotter import FilePlotter
4>>> tt = FilePlotter(title="Crosstalk probabilities",show_title=True,show_legend=True)
5>>> tt.addFile("crosstalk_050.txt",title=True,axislabels=True,legend=True,xyplot=True)
6x-Axis: Overvoltage (V)
7y-Axis: Crosstalk probability
8Labels: ['', '050C']
9>>> tt.addFile("crosstalk_100.txt",title=True,axislabels=True,legend=True,xyplot=True)
10Labels: ['', '100C']
11>>> tt.show()
12"""
13"""Usage: python plotFile.py [-h|--help] [-x|--xyplot] filename
14Options:
15-h|--help: Show this help
16-x|--xyplot: Use first columns as x-values
17-t|--title: Use first three lines of the file as title, x-label, y-label
18-l|--legend: Show legend from column titles
19"""
20import os,sys
21import getopt
22import numpy as np
23from math import *
24from ROOT import TCanvas, TMultiGraph, TGraph, TGraphErrors
25from ROOT import gROOT, gStyle
26from ROOT import TH2F
27
28gROOT.SetStyle("Plain")
29
30#*******************************************************************************
31class FilePlotter:
32 def __init__(self,show_legend=True,show_title=False,yrange=False,title=None,title_x=None,title_y=None,out_name=None,xmin=None,xmax=None,show_line=False):
33 #Todo: doc-strings
34 #ToDo: implement file calling (ie. "plotFile.py data.txt")
35 #Todo: format size of the legend (self.canvLegend.GetNRows())
36 #Todo: implement x-min/max > datapoints...
37 #Todo: implement errors
38
39 #-------------------------------------
40 #Read constructor arguments
41 #-------------------------------------
42 self.show_legend = show_legend #Whether to show the legend, will be put to false if one of the files lacks legend information
43 self.show_title = show_title
44 self.show_line = show_line
45
46 self.yrange = False
47 self.ymin = np.nan
48 self.ymax = np.nan
49
50 self.title = title
51 self.title_x = title_x
52 self.title_y = title_y
53
54 self.out_name = out_name
55
56 self.xmin = xmin
57 self.xmax = xmax
58 if self.xmin is None and self.xmax is not None:
59 self.xmin = self.xmax-1
60 if self.xmin is not None and self.xmax is None:
61 self.xmax = self.xmin+1
62
63 #-------------------------------------
64 #Define empty canvas
65 #-------------------------------------
66 self.canv = None
67 #ToDo: hide if possible
68
69 #-------------------------------------
70 #Create graphs
71 #-------------------------------------
72 self.allGraphs = TMultiGraph("allgraphs","allGraphs")
73 self.graphs = []
74
75 def addFile(self,filename,title=False,axislabels=False,legend=True,xyplot=False,xyerror=False):
76 #-------------------------------------
77 #Define titles and legend
78 #-------------------------------------
79 skip_lines = 0
80
81 file = open(filename)
82
83 if title:
84 skip_lines += 1
85 tmp = file.readline().strip() #strip() to remove the \n at the end
86 if self.title is None:
87 self.title = tmp
88 print "Title: ", self.title
89
90 if axislabels:
91 skip_lines += 2
92 tmp = file.readline().strip()
93 if self.title_x is None:
94 self.title_x = tmp
95 print "x-Axis: ", self.title_x
96 tmp = file.readline().strip()
97 if self.title_y is None:
98 self.title_y = tmp
99 print "y-Axis: ", self.title_y
100
101 if legend:
102 skip_lines += 1
103 labels = file.readline().strip("\r\n").split("\t") #only strip \n, otherwise problem if no label is given for first column
104 print "Labels: ", labels
105 elif self.show_legend:
106 print "Legend missing, deactivating show_legend."
107 self.show_legend = False
108
109 file.close()
110
111 #-------------------------------------
112 #Check output filename
113 #-------------------------------------
114 if self.out_name is None:
115 self.out_name = filename
116
117 #-------------------------------------
118 #Read file
119 #-------------------------------------
120 data = np.genfromtxt(filename, skip_header=skip_lines, invalid_raise=False, unpack=True, usemask=True)
121 #no delimiter usually does the right thing (eg. recognize multiple spaces)
122 #invalid_raise=False to handle corrupt (eg. last) lines
123 #print data
124
125 if(xyerror):
126 validValues = np.isfinite(data[0])*np.isfinite(data[1])*np.isfinite(data[2])*np.isfinite(data[3])
127 baseX = data[0].compress(validValues)
128 baseXerror = data[1].compress(validValues)
129 values = data[2].compress(validValues)
130 valuesError = data[3].compress(validValues)
131 colmin = np.min(values)
132 colmax = np.max(values)
133 if(np.isnan(self.ymin) or colmin<self.ymin):
134 self.ymin=colmin
135 if(np.isnan(self.ymax) or colmin>self.ymax):
136 self.ymax=colmax
137 self.graphs.append(TGraphErrors(len(values),baseX,values,baseXerror,valuesError))
138
139 #-------------------------------------
140 #Graph properties
141 #-------------------------------------
142 if legend:
143 self.graphs[-1].SetTitle(labels[2])
144 self.graphs[-1].SetMarkerColor(len(self.graphs)) #TColor.GetColor("#000000")
145 self.graphs[-1].SetMarkerStyle(20)
146 self.graphs[-1].SetFillStyle(0)
147 self.allGraphs.Add(self.graphs[-1])
148 return
149
150 if (xyplot):
151 baseX = data[0]
152 data = data[1:]
153 if legend:
154 labels = labels[1:]
155 else:
156 print len(data[0])
157 baseX = np.arange(0,len(data[0]),1.0) #must be with 1.0, otherwise an integer array
158
159 if legend:
160 if self.show_legend and not len(data)==len(labels):
161 print "Not the same amount of labels as columns, deactivating show_legend."
162 self.show_legend = False
163
164 #-------------------------------------
165 #Add data to graphs
166 #-------------------------------------
167 for i,column in enumerate(data):
168 # column = np.nan_to_num(np.array(column)) #Sets all the nan to 0, replaced by the handling below (ommiting values)
169 column = np.array(column)
170 x = baseX
171 x = x.compress(np.isfinite(column)*np.isfinite(baseX)) #only take entries where both x and y are valid
172 column = column.compress(np.isfinite(column)*np.isfinite(baseX))
173 colmin = np.min(column)
174 colmax = np.max(column)
175 if(np.isnan(self.ymin) or colmin<self.ymin):
176 self.ymin=colmin
177 if(np.isnan(self.ymax) or colmin>self.ymax):
178 self.ymax=colmax
179 self.graphs.append(TGraph(len(column),x,column))
180
181 #-------------------------------------
182 #Graph properties
183 #-------------------------------------
184 if legend:
185 self.graphs[-1].SetTitle(labels[i])
186 self.graphs[-1].SetMarkerColor(len(self.graphs)) #TColor.GetColor("#000000")
187 self.graphs[-1].SetMarkerStyle(20)
188 self.graphs[-1].SetFillStyle(0)
189 self.allGraphs.Add(self.graphs[-1])
190
191 def canvas(self):
192 #Create a canvas
193 if not isinstance(self.canv,TCanvas):
194 print "Creating canvas..."
195 self.canv = TCanvas("canv","canv",10,10,750,450)
196
197 def show(self):
198 #-------------------------------------
199 #Create canvas if necessary (eg. if window closed)
200 #-------------------------------------
201 self.canvas()
202
203 #-------------------------------------
204 #Clear canvas (important if called multiple times)
205 #-------------------------------------
206 self.canv.Clear()
207
208 #-------------------------------------
209 #Set title
210 #-------------------------------------
211 if self.title is None:
212 self.title = "Plot title"
213 self.allGraphs.SetTitle(self.title)
214
215 #-------------------------------------
216 #Extend the x-axis range
217 #-------------------------------------
218 if self.xmin is not None and self.xmax is not None and not isinstance(self.tmp_histo,TH2F):
219 self.tmp_histo = TH2F("tmp_histo","tmp_histo",1,self.xmin,self.xmax,1,self.ymin,self.ymax)
220 self.tmp_histo.Draw()
221
222 #-------------------------------------
223 #Draw graphs
224 #-------------------------------------
225 if not self.show_title:
226 gStyle.SetOptTitle(0)
227 self.canv.cd()
228 if(self.show_line):
229 self.allGraphs.Draw("AL")
230 else:
231 self.allGraphs.Draw("AP")
232
233 if self.title_x is None:
234 self.title_x = "x-Axis"
235 if self.title_y is None:
236 self.title_y = "y-Axis"
237
238 self.allGraphs.GetXaxis().SetTitle(self.title_x)
239 self.allGraphs.GetYaxis().SetTitle(self.title_y)
240
241 if(self.yrange):
242 print "y-Axis range: ", self.ymin, self.ymax
243 allGraphs.GetYaxis().SetRangeUser(self.ymin,self.ymax)
244
245 #-------------------------------------
246 #Legend
247 #-------------------------------------
248 if(self.show_legend):
249 self.canvLegend = self.canv.BuildLegend(0.15,0.67,0.53,0.88,"") #Using standard size and position also does not account for the number of entries
250 self.canvLegend.SetFillColor(0) #TColor.GetColor("#FFFFFF"))
251
252 #-------------------------------------
253 #Show the canvas
254 #-------------------------------------
255 self.canv.Modified()
256 self.canv.Update()
257
258 def save(self):
259 #-------------------------------------
260 #Save the plots
261 #-------------------------------------
262 filenameNoExt,tmp = os.path.splitext(os.path.basename(self.out_name))
263 self.canv.Print(filenameNoExt+"_plot.root","root") #Change to "root,RECREATE" if necessary
264 self.canv.Print(filenameNoExt+"_plot.pdf","pdf")
265 self.canv.Print(filenameNoExt+"_plot.png","png")
266
267##*******************************************************************************
268#if __name__ == "__main__":
269# filename = r'/home/thomas/docs/Python/Examples/plotFile/72.TXT'
270# xyplot = False
271# legend = False
272# titles = False
273#
274# #Get the command line options
275# try:
276# opts, args = getopt.getopt(sys.argv[1:], "hlxt", ["help,legend,xyplot,titles"])
277# except getopt.error, msg:
278# print msg
279# print "For help use --help"
280# sys.exit(2)
281#
282# #Parse options
283# for option, argument in opts:
284# #Help
285# if option in ("-h", "--help"):
286# print __doc__
287# print plotFile.__doc__
288# sys.exit(0)
289#
290# #X-Y Plot (use first column as x)
291# elif option in ("-x", "--xyplot"):
292# print "xyplot = True (using first column as x values)"
293# xyplot = True
294#
295# #Show legend
296# elif option in ("-l", "--legend"):
297# print "legend = True (show legend)"
298# legend = True
299#
300# #Use first three lines for titles
301# elif option in ("-t", "--titles"):
302# print "titles = True (use titles)"
303# titles = True
304#
305# #Get project name
306# if len(args)>1:
307# print "More than one argument provided."
308# print "For help use --help"
309# sys.exit(2)
310# elif len(args)==1:
311# filename = os.path.abspath(args[0])
312# print "File name set to:", filename,"\n"
313# else:
314# print "Default file name used: ", filename,"\n"
315#
316# plotFile(filename,xyplot,legend,titles)
Note: See TracBrowser for help on using the repository browser.