2 This module is graphical API using pymatplotlib.
4 -- We use matplotlib OO class level api, we do not use its high-level helper modules. Favor endured stability over simplicity.
5 -- use TkAgg for interactive mode. Beaware of Tk,pyTk installation defects in various cern distributions.
6 -- PNG as default batch file format
7 -- we support http mode by sending string buf via meme type image/png. Sending a premade static plot to webserver is considered a uploading process instead of http dynamic graphical mode. Therefore covered in this module.
12 from RecoLuminosity.LumiDB
import CommonUtil
15 if not os.environ.has_key(
'DISPLAY')
or not os.environ[
'DISPLAY']:
17 matplotlib.use(
'Agg',warn=
False)
18 from matplotlib.backends.backend_agg
import FigureCanvasAgg
as CanvasBackend
21 matplotlib.use(
'TkAgg',warn=
False)
22 from matplotlib.backends.backend_tkagg
import FigureCanvasTkAgg
as CanvasBackend
23 from matplotlib.backends.backend_tkagg
import NavigationToolbar2TkAgg
26 root.wm_title(
"Lumi GUI in TK")
28 print 'unable to import GUI backend, switch to batch only mode'
29 matplotlib.use(
'Agg',warn=
False)
30 from matplotlib.backends.backend_agg
import FigureCanvasAgg
as CanvasBackend
33 from matplotlib.figure
import Figure
34 from matplotlib.font_manager
import fontManager,FontProperties
35 matplotlib.rcParams[
'lines.linewidth']=1.5
36 matplotlib.rcParams[
'grid.linewidth']=0.2
37 matplotlib.rcParams[
'xtick.labelsize']=11
38 matplotlib.rcParams[
'ytick.labelsize']=11
39 matplotlib.rcParams[
'legend.fontsize']=10
40 matplotlib.rcParams[
'axes.labelsize']=11
41 matplotlib.rcParams[
'font.weight']=567
65 xidx.append(rawxdata.index(x))
68 print '[WARNING]: no data, do nothing'
70 t=sum(rawydata[
'Delivered'])
72 unitstring=
'$\mu$b$^{-1}$'
73 if t>=1.0e3
and t<1.0e06:
75 unitstring=
'nb$^{-1}$'
76 elif t>=1.0e6
and t<1.0e9:
78 unitstring=
'pb$^{-1}$'
79 elif t>=1.0e9
and t<1.0e12:
81 unitstring=
'fb$^{-1}$'
82 elif t>=1.0e12
and t<1.0e15:
84 unitstring=
'ab$^{-1}$'
85 for ylabel,yvalues
in rawydata.items():
88 ypoints[ylabel].
append(sum(yvalues[0:i])/denomitor)
89 ytotal[ylabel]=sum(yvalues)/denomitor
90 ax=self.__fig.add_subplot(111)
92 ax.set_yscale(
'linear')
96 raise 'unsupported yscale ',yscale
97 ax.set_xlabel(
r'Run',position=(0.95,0))
98 ax.set_ylabel(
r'L '+unitstring,position=(0,0.9))
99 xticklabels=ax.get_xticklabels()
100 for tx
in xticklabels:
102 majorLocator=matplotlib.ticker.LinearLocator( nticks )
103 majorFormatter=matplotlib.ticker.FormatStrFormatter(
'%d')
104 minorLocator=matplotlib.ticker.LinearLocator(numticks=4*nticks)
105 ax.xaxis.set_major_locator(majorLocator)
106 ax.xaxis.set_major_formatter(majorFormatter)
107 ax.xaxis.set_minor_locator(minorLocator)
108 ax.set_xbound(lower=xpoints[0],upper=xpoints[-1])
110 keylist=ypoints.keys()
113 for ylabel
in keylist:
115 if self.colormap.has_key(ylabel):
117 ax.plot(xpoints,ypoints[ylabel],label=ylabel,color=cl,drawstyle=
'steps')
118 legendlist.append(ylabel+
' '+
'%.2f'%(ytotal[ylabel])+
' '+unitstring)
121 trans=matplotlib.transforms.BlendedGenericTransform(ax.transData,ax.transAxes)
122 ax.text(xpoints[0],1.025,str(xpoints[0]),transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
123 ax.text(xpoints[-1],1.025,str(xpoints[-1]),transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
124 ax.legend(tuple(legendlist),loc=
'upper left')
125 self.__fig.subplots_adjust(bottom=0.18,left=0.1)
127 def plotSumX_Fill(self,rawxdata,rawydata,rawfillDict,nticks=6,yscale='linear'):
131 xpoints=rawfillDict.keys()
133 print '[WARNING]: no data, do nothing'
138 t=sum(rawydata[
'Delivered'])
140 unitstring=
'$\mu$b$^{-1}$'
141 if t>=1.0e3
and t<1.0e06:
143 unitstring=
'nb$^{-1}$'
144 elif t>=1.0e6
and t<1.0e9:
146 unitstring=
'pb$^{-1}$'
147 elif t>=1.0e9
and t<1.0e12:
149 unitstring=
'fb$^{-1}$'
150 elif t>=1.0e12
and t<1.0e15:
152 unitstring=
'ab$^{-1}$'
154 for ylabel,yvalue
in rawydata.items():
156 ytotal[ylabel]=sum(rawydata[ylabel])/denomitor
157 for idx,fill
in enumerate(xpoints):
158 runlist=rawfillDict[fill]
160 beginfo=str(fill)+
':'+str(runlist[0])
161 if idx==len(xpoints)-1:
162 endinfo=str(fill)+
':'+str(runlist[-1])
163 xidx=rawxdata.index(
max(runlist))
164 ypoints[ylabel].
append(sum(yvalue[0:xidx])/denomitor)
165 ax=self.__fig.add_subplot(111)
166 ax.set_xlabel(
r'LHC Fill Number',position=(0.84,0))
167 ax.set_ylabel(
r'L '+unitstring,position=(0,0.9))
168 ax.set_xbound(lower=xpoints[0],upper=xpoints[-1])
170 ax.set_yscale(
'linear')
174 raise 'unsupported yscale ',yscale
175 xticklabels=ax.get_xticklabels()
176 majorLocator=matplotlib.ticker.LinearLocator( nticks )
177 majorFormatter=matplotlib.ticker.FormatStrFormatter(
'%d')
179 ax.xaxis.set_major_locator(majorLocator)
180 ax.xaxis.set_major_formatter(majorFormatter)
183 keylist=ypoints.keys()
186 for ylabel
in keylist:
188 if self.colormap.has_key(ylabel):
190 ax.plot(xpoints,ypoints[ylabel],label=ylabel,color=cl,drawstyle=
'steps')
191 legendlist.append(ylabel+
' '+
'%.2f'%(ytotal[ylabel])+
' '+unitstring)
194 trans=matplotlib.transforms.BlendedGenericTransform(ax.transData,ax.transAxes)
195 ax.text(xpoints[0],1.025,beginfo,transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
196 ax.text(xpoints[-1],1.025,endinfo,transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
197 ax.legend(tuple(legendlist),loc=
'upper left')
198 self.__fig.subplots_adjust(bottom=0.1,left=0.1)
200 def plotSumX_Time(self,rawxdata,rawydata,minTime,maxTime,hltpath='',nticks=6,annotateBoundaryRunnum=False,yscale='linear'):
203 rawxdata runDict{runnumber:[delivered,recorded,recorded_hltpath]}
204 rawydata {label:[rundata]}
212 for idx,run
in enumerate(runs):
213 xpoints.append(matplotlib.dates.date2num(rawxdata[run][0]))
216 print '[WARNING]: no data, do nothing'
218 t=sum(rawydata[
'Delivered'])
220 unitstring=
'$\mu$b$^{-1}$'
221 if t>=1.0e3
and t<1.0e06:
223 unitstring=
'nb$^{-1}$'
224 elif t>=1.0e6
and t<1.0e9:
226 unitstring=
'pb$^{-1}$'
227 elif t>=1.0e9
and t<1.0e12:
229 unitstring=
'fb$^{-1}$'
230 elif t>=1.0e12
and t<1.0e15:
232 unitstring=
'ab$^{-1}$'
234 for ylabel,yvalue
in rawydata.items():
237 ypoints[ylabel].
append(sum(yvalue[0:i])/denomitor)
238 ytotal[ylabel]=sum(yvalue)/denomitor
239 ax=self.__fig.add_subplot(111)
241 ax.set_yscale(
'linear')
245 raise 'unsupported yscale ',yscale
246 dateFmt=matplotlib.dates.DateFormatter(
'%d/%m')
247 majorLoc=matplotlib.ticker.LinearLocator(numticks=nticks)
248 ax.xaxis.set_major_locator(majorLoc)
249 minorLoc=matplotlib.ticker.LinearLocator(numticks=nticks*4)
250 ax.xaxis.set_major_formatter(dateFmt)
251 ax.set_xlabel(
r'Date',position=(0.84,0))
252 ax.set_ylabel(
r'L '+unitstring,position=(0,0.9))
253 ax.xaxis.set_minor_locator(minorLoc)
254 ax.set_xbound(lower=xpoints[0],upper=xpoints[-1])
255 xticklabels=ax.get_xticklabels()
256 for tx
in xticklabels:
257 tx.set_horizontalalignment(
'left')
259 keylist=ypoints.keys()
262 for ylabel
in keylist:
264 if self.colormap.has_key(ylabel):
266 ax.plot(xpoints,ypoints[ylabel],label=ylabel,color=cl,drawstyle=
'steps')
267 legendlist.append(ylabel+
' '+
'%.2f'%(ytotal[ylabel])+
' '+unitstring)
269 trans=matplotlib.transforms.BlendedGenericTransform(ax.transData,ax.transAxes)
272 if annotateBoundaryRunnum:
273 ax.text(xpoints[0],1.025,str(runs[0]),transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
274 ax.text(xpoints[-1],1.025,str(runs[-1]),transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
275 yearStr=minTime.strftime(
'%Y')
276 firstimeStr=minTime.strftime(
'%b %d %H:%M')
277 lasttimeStr=maxTime.strftime(
'%b %d %H:%M')
278 ax.set_title(
'Total Integrated Luminosity '+yearStr+
' ('+firstimeStr+
' UTC - '+lasttimeStr+
' UTC)',size=
'small',family=
'fantasy')
279 ax.legend(tuple(legendlist),loc=
'upper left')
280 self.__fig.autofmt_xdate(bottom=0.18,rotation=0)
281 self.__fig.subplots_adjust(bottom=0.1,left=0.1)
283 def plotPerdayX_Time(self,days,databyday,minTime,maxTime,boundaryInfo=[],nticks=6,annotateBoundaryRunnum=False,yscale='linear'):
285 databyday {'Delivered':[lumiperday]}
286 boundaryInfo [[begintime,begininfo],[endtime,endinfo]]
288 ax=self.__fig.add_subplot(111)
289 t=
max(databyday[
'Delivered'])
290 minvar=
min([x
for x
in databyday[
'Recorded']
if x>0])
292 keylist=databyday.keys()
295 maxvalues[k]=
max(databyday[k])
298 ax.set_yscale(
'linear')
302 for i,v
in enumerate(databyday[k]):
304 databyday[k][i]=minvar
306 raise 'unsupported yscale ',yscale
307 dateFmt=matplotlib.dates.DateFormatter(
'%d/%m')
308 majorLoc=matplotlib.ticker.LinearLocator(numticks=nticks)
309 minorLoc=matplotlib.ticker.LinearLocator(numticks=nticks*4)
310 ax.xaxis.set_major_formatter(dateFmt)
311 ax.set_xlabel(
r'Date',position=(0.84,0))
312 ax.xaxis.set_major_locator(majorLoc)
313 ax.xaxis.set_minor_locator(minorLoc)
314 xticklabels=ax.get_xticklabels()
315 for tx
in xticklabels:
316 tx.set_horizontalalignment(
'right')
321 unitstring=
'$\mu$b$^{-1}$'
322 if t>=1.0e3
and t<1.0e06:
324 unitstring=
'nb$^{-1}$'
325 elif t>=1.0e6
and t<1.0e9:
327 unitstring=
'pb$^{-1}$'
328 elif t>=1.0e9
and t<1.0e12:
330 unitstring=
'fb$^{-1}$'
331 elif t>=1.0e12
and t<1.0e15:
333 unitstring=
'ab$^{-1}$'
335 ax.set_ylabel(
r'L '+unitstring,position=(0,0.9))
336 for ylabel
in keylist:
338 if self.colormap.has_key(ylabel):
340 ax.plot(days,[y/denomitor
for y
in databyday[ylabel]],label=ylabel,color=cl,drawstyle=
'steps')
341 legendlist.append(ylabel+
' Max '+
'%.2f'%(maxvalues[ylabel]/denomitor)+
' '+unitstring)
342 ax.legend(tuple(legendlist),loc=
'upper left')
343 ax.set_xbound(lower=matplotlib.dates.date2num(minTime),upper=matplotlib.dates.date2num(maxTime))
344 if annotateBoundaryRunnum:
345 if len(boundaryInfo)!=0:
346 begtime=boundaryInfo[0][0]
347 beginfo=boundaryInfo[0][1]
348 endtime=boundaryInfo[1][0]
349 endinfo=boundaryInfo[1][1]
351 trans=matplotlib.transforms.BlendedGenericTransform(ax.transData,ax.transAxes)
352 ax.text(matplotlib.dates.date2num(begtime),1.025,beginfo,transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
353 ax.text(matplotlib.dates.date2num(endtime),1.025,endinfo,transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
354 yearStr=minTime.strftime(
'%Y')
355 firstimeStr=minTime.strftime(
'%b %d %H:%M')
356 lasttimeStr=maxTime.strftime(
'%b %d %H:%M')
357 ax.set_title(
'Integrated Luminosity/Day '+yearStr+
' ('+firstimeStr+
' UTC - '+lasttimeStr+
' UTC)',size=
'small',family=
'fantasy')
358 self.__fig.autofmt_xdate(bottom=0.18,rotation=0)
359 self.__fig.subplots_adjust(bottom=0.18,left=0.1)
361 def plotPeakPerday_Time(self,daydict,minTime,maxTime,nticks=6,annotateBoundaryRunnum=False,yscale='linear'):
363 Input: daydict={}#{day:[run,lsnum,instlumi]}
370 beginfo=str(daydict[days[0]][0])+
':'+str(daydict[days[0]][1])
371 endinfo=str(daydict[days[-1]][0])+
':'+str(daydict[days[-1]][1])
378 for day
in range(minday,maxday+1):
380 if not daydict.has_key(day):
383 daymaxdata=daydict[day]
384 ypoints.append(daymaxdata[2])
385 if daydict[day][2]>ymax:
388 runmax=daydict[day][0]
389 lsmax=daydict[day][1]
390 maxinfo=str(runmax)+
':'+str(lsmax)
392 unitstring=
'$\mu$b$^{-1}$s$^{-1}$'
393 if ymax>=1.0e3
and ymax<1.0e06:
395 unitstring=
'nb$^{-1}$s$^{-1}$'
396 elif ymax>=1.0e6
and ymax<1.0e9:
398 unitstring=
'pb$^{-1}$s$^{-1}$'
399 elif ymax>=1.0e9
and ymax<1.0e12:
401 unitstring=
'fb$^{-1}$s$^{-1}$'
402 elif ymax>=1.0e12
and ymax<1.0e15:
404 unitstring=
'ab$^{-1}$s$^{-1}$'
406 ax=self.__fig.add_subplot(111)
408 ax.set_yscale(
'linear')
411 for i,v
in enumerate(ypoints):
415 raise 'unsupported yscale ',yscale
416 dateFmt=matplotlib.dates.DateFormatter(
'%d/%m')
417 majorLoc=matplotlib.ticker.LinearLocator(numticks=nticks)
418 minorLoc=matplotlib.ticker.LinearLocator(numticks=nticks*4)
419 ax.xaxis.set_major_formatter(dateFmt)
420 ax.set_xlabel(
r'Date',position=(0.84,0))
421 ax.set_ylabel(
r'L '+unitstring,position=(0,0.9))
422 ax.xaxis.set_major_locator(majorLoc)
423 ax.xaxis.set_minor_locator(minorLoc)
424 xticklabels=ax.get_xticklabels()
425 for tx
in xticklabels:
426 tx.set_horizontalalignment(
'right')
434 ax.plot(xpoints,[y/denomitor
for y
in ypoints],label=
'Max Inst',color=cl,drawstyle=
'steps')
435 legendlist.append(
'Max Inst %.2f'%(ymax/denomitor)+
' '+unitstring)
436 ax.legend(tuple(legendlist),loc=
'upper left')
437 ax.set_xbound(lower=matplotlib.dates.date2num(minTime),upper=matplotlib.dates.date2num(maxTime))
438 if annotateBoundaryRunnum:
440 trans=matplotlib.transforms.BlendedGenericTransform(ax.transData,ax.transAxes)
441 ax.text(xpoints[0],1.025,beginfo,transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
442 ax.text(xpoints[-1],1.025,endinfo,transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
443 ax.annotate(maxinfo,xy=(xmax,ymax),xycoords=
'data',xytext=(0,13),textcoords=
'offset points',arrowprops=
dict(facecolor=
'green',shrink=0.05),size=
'x-small',horizontalalignment=
'center',color=
'green',bbox=
dict(facecolor=
'white'))
444 yearStr=minTime.strftime(
'%Y')
445 firstimeStr=minTime.strftime(
'%b %d %H:%M')
446 lasttimeStr=maxTime.strftime(
'%b %d %H:%M')
447 ax.set_title(
'Peak Luminosity/Day '+yearStr+
' ('+firstimeStr+
' UTC - '+lasttimeStr+
' UTC)',size=
'small',family=
'fantasy')
448 self.__fig.autofmt_xdate(bottom=0.18,rotation=0)
449 self.__fig.subplots_adjust(bottom=0.1,left=0.1)
453 Input: rawxdata [run,fill,norbit,starttime,stoptime,totalls,ncmsls]
454 rawydata {label:[instlumi]}
459 starttime=rawxdata[3]
463 peakinst=
max(rawydata[
'Delivered'])
464 lslength=float(norbit)*3564*25.0e-9
465 totaldelivered=sum(rawydata[
'Delivered'])*lslength
466 totalrecorded=sum(rawydata[
'Recorded'])*lslength
467 xpoints=range(1,totalls+1)
471 for ylabel,yvalue
in rawydata.items():
472 ypoints[ylabel]=yvalue
473 ymax[ylabel]=
max(yvalue)
478 bottom_h=bottom+height
479 rect_scatter=[left,bottom,width,height]
480 rect_table=[left,bottom_h,width,0.25]
482 nullfmt=matplotlib.ticker.NullFormatter()
483 nullloc=matplotlib.ticker.NullLocator()
484 axtab=self.__fig.add_axes(rect_table,frameon=
False)
486 axtab.xaxis.set_major_formatter(nullfmt)
487 axtab.yaxis.set_major_formatter(nullfmt)
488 axtab.xaxis.set_major_locator(nullloc)
489 axtab.yaxis.set_major_locator(nullloc)
491 ax=self.__fig.add_axes(rect_scatter)
493 majorLoc=matplotlib.ticker.LinearLocator(numticks=nticks)
494 minorLoc=matplotlib.ticker.LinearLocator(numticks=nticks*4)
495 ax.set_xlabel(
r'LS',position=(0.96,0))
496 ax.set_ylabel(
r'L $\mu$b$^{-1}$s$^{-1}$',position=(0,0.9))
497 ax.xaxis.set_major_locator(majorLoc)
498 ax.xaxis.set_minor_locator(minorLoc)
499 ax.set_xbound(lower=xpoints[0],upper=xpoints[-1])
500 xticklabels=ax.get_xticklabels()
501 for tx
in xticklabels:
502 tx.set_horizontalalignment(
'right')
504 keylist=ypoints.keys()
508 for ylabel
in keylist:
510 if self.colormap.has_key(ylabel):
512 ax.plot(xpoints,ypoints[ylabel],
'.',label=ylabel,color=cl)
513 legendlist.append(ylabel)
515 ax.axvline(xpoints[ncmsls-1],color=
'green',linewidth=0.2)
519 if totaldelivered>=1.0e3
and totaldelivered<1.0e06:
522 elif totaldelivered>=1.0e6
and totaldelivered<1.0e9:
525 elif totaldelivered>=1.0e9
and totaldelivered<1.0e12:
528 elif totaldelivered>=1.0e12
and totaldelivered<1.0e15:
531 colLabels=(
'run',
'fill',
'max inst(/$\mu$b/s)',
'delivered('+unitstring+
')',
'recorded('+unitstring+
')')
532 cellText=[[str(runnum),str(fill),
'%.3f'%(peakinst),
'%.3f'%(totaldelivered/denomitor),
'%.3f'%(totalrecorded/denomitor)]]
534 sumtable=axtab.table(cellText=cellText,colLabels=colLabels,colWidths=[0.12,0.1,0.27,0.27,0.27],cellLoc=
'center',loc=
'center')
535 trans=matplotlib.transforms.BlendedGenericTransform(ax.transData,ax.transAxes)
536 axtab.add_table(sumtable)
538 ax.text(xpoints[0],1.02,starttime[0:17],transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
539 ax.text(xpoints[ncmsls-1],1.02,stoptime[0:17],transform=trans,horizontalalignment=
'left',size=
'x-small',color=
'green',bbox=
dict(facecolor=
'white'))
540 ax.legend(tuple(legendlist),loc=
'upper right',numpoints=1)
544 cherrypy.response.headers[
'Content-Type']=
'image/png'
546 self.__canvas.print_png(buf)
547 return buf.getvalue()
551 self.__canvas.print_figure(filename)
555 print 'interactive mode is not available for your setup, exit'
559 self.__canvas.get_tk_widget().
pack(side=Tk.TOP,fill=Tk.BOTH,expand=1)
560 toolbar=NavigationToolbar2TkAgg(self.
__canvas,root)
562 self.__canvas._tkcanvas.pack(side=Tk.TOP,fill=Tk.BOTH,expand=1)
563 button = Tk.Button(master=root,text=
'Quit',command=sys.exit)
564 button.pack(side=Tk.BOTTOM)
566 if __name__==
'__main__':
567 fig=Figure(figsize=(5,5),dpi=100)
568 a=fig.add_subplot(111)
569 t=numpy.arange(0.0,3.0,0.01)
570 s=numpy.sin(2*numpy.pi*t)
573 m.drawPNG(
'testmatplotrender.png')
const T & max(const T &a, const T &b)