Package medite :: Package GUI :: Module FMPanel
[hide private]
[frames] | no frames]

Source Code for Module medite.GUI.FMPanel

  1  # -*- coding: iso-8859-1 -*- 
  2  # Copyright 20003 - 2008: Julien Bourdaillet (julien.bourdaillet@lip6.fr), Jean-Gabriel Ganascia (jean-gabriel.ganascia@lip6.fr) 
  3  # This file is part of MEDITE. 
  4  # 
  5  #    MEDITE is free software; you can redistribute it and/or modify 
  6  #    it under the terms of the GNU General Public License as published by 
  7  #    the Free Software Foundation; either version 2 of the License, or 
  8  #    (at your option) any later version. 
  9  # 
 10  #    MEDITE is distributed in the hope that it will be useful, 
 11  #    but WITHOUT ANY WARRANTY; without even the implied warranty of 
 12  #    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the 
 13  #    GNU General Public License for more details. 
 14  # 
 15  #    You should have received a copy of the GNU General Public License 
 16  #    along with Foobar; if not, write to the Free Software 
 17  #    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 18   
 19  import MediteAppli.synthetic 
 20  #import scipy 
 21  from matplotlib.numerix import arange 
 22  import matplotlib.numerix.random_array 
 23  #import pytz.zoneinfo.UTC 
 24  import matplotlib 
 25  #import Numeric 
 26  import numpy.oldnumeric as Numeric 
 27   
 28  # uncomment the following to use wx rather than wxagg 
 29  #matplotlib.use('WX') 
 30  #from matplotlib.backends.backend_wx import FigureCanvasWx as FigureCanvas 
 31   
 32  # comment out the following to use wx rather than wxagg 
 33  matplotlib.use('WXAgg') 
 34  from matplotlib.backends.backend_wxagg import FigureCanvasWxAgg as FigureCanvas 
 35  from matplotlib.backends.backend_wxagg import NavigationToolbar2WxAgg  
 36   
 37  from matplotlib.backends.backend_wx import _load_bitmap 
 38  from matplotlib.figure import Figure 
 39  from matplotlib.numerix.mlab import rand 
 40  from matplotlib.patches import Rectangle 
 41  from matplotlib.axes import Axes 
 42  import wx 
 43  #from wxPython.wx import * 
 44  from pylab import connect 
 45   
46 -class ColorManager(MediteAppli.synthetic.ListManager):
47 """ Classe centralisant la gestion de la liste de opération génétiques utilisées """
48 - def __init__(self,length=None):
49 self._liste = ['blue', 'green', 'red', 'cyan', 'magenta', 'yellow', 50 '#abbbcc', '#fbccdd', '#bcddee', '#edeeff', '#aeffaa', '#ffaabb', 51 '#bcbbaa', '#edccbb', '#aeddcc'] 52 if length != None: 53 self._liste = self._liste[:length]
54
55 -class FMPanel(wx.Panel):
56 """ Panel générique """
57 - def __init__(self, frame, fm):
58 """ Constructeur 59 pre: isinstance(fm,MediteAppli.synthetic.FrequencyMatrix) 60 """ 61 wx.Panel.__init__(self,frame) 62 self.fm = fm 63 self.tm = fm.getItemLegend() 64 self.cm = ColorManager() 65 self.potm = fm.getGraphLegend()
66 - def param(self):
67 self.title = ""
68 - def debutInitFMPanel(self):
69 self.param() 70 self.figure = Figure(figsize=(300,300), dpi=65) #figure sur laquelle on dessine 71 self.figure.text(0.05,0.95,self.title) 72 self.axes = {} # ensemble des graphiques de la figure 73 self.handles=[] #liste des rectanlges nécessaires pour la légende
74 - def finInitFMPanel(self):
75 self.canvas = FigureCanvas(self, -1, self.figure) # canevas 76 self.sizer = wx.BoxSizer(wx.VERTICAL) # aligneur 77 self.sizer.Add(self.canvas, 1, wx.TOP | wx.LEFT | wx.EXPAND) 78 #EVT_PAINT(self, self.OnPaint) # Capture the paint message 79 #self.canvas.mpl_connect('motion_notify_event', self.OnMove) # Capture the paint message 80 self.SetSizer(self.sizer) 81 self.Fit()
82 - def OnPaint(self, event):
83 self.canvas.draw() 84 event.Skip()
85 - def OnMove(self, event):
86 # get the x and y pixel coords 87 x, y = event.x, event.y 88 if event.inaxes: 89 axe = event.inaxes 90 xaxis = axe.get_xaxis() 91 fig = axe.get_figure() 92 print xaxis.get_data_interval() 93 print 'data coords', event.xdata, event.ydata
94 95
96 -class FMPanelHisto(FMPanel):
97 """ Frequency Matrix Panel, panel affichant une Matrice de fréquences sous 98 la forme d'un ensemble de graphiques en histogrammes. Chaque graphique en histogramme 99 représente une partie du texte (ins, supp...) et chaque histogramme une étiquette"""
100 - def __init__(self, frame, fm=None):
101 """ 102 pre: isinstance(fm,MediteAppli.synthetic.TagFrequencyMatrix) 103 """ 104 FMPanel.__init__(self,frame,fm) 105 106 self.debutInitFMPanel() 107 nbLine = self.fm.getNbLine() # nb lignes 108 nbCol = 1 # nb colonnes 109 self.figure.subplots_adjust(hspace=0.001) # colle les graphes l'un contre l'autre 110 self.axes[0] = self.write_axe(0,nbLine,nbCol,self.handles) # crée un graphe 111 for i in xrange(1,nbLine-2): # crée les autres, les parties de texte seulement 112 self.write_axe(i,nbLine,nbCol,self.handles) 113 for i in xrange(nbLine-2,nbLine): # crée les 2 derniers pour les textes totaux 114 self.write_axe2(i,nbLine,nbCol,self.handles) 115 self.figure.legend(self.handles,self.tm.getDescriptions(),'upper right', 116 handlelen = 0.01, handletextsep = 0.01) # légende 117 self.finInitFMPanel()
118 - def param(self):
119 self.title = u"Nombre d'étiquettes dans chaque partie du texte"
120 - def write_axe(self, num,nbLine,nbCol,handles):
121 """ Fonction dessinant effectivement le num-ième graphique parmi nbLine*nbCol en se limitant aux parties du texte""" 122 if num==0: 123 self.axes[num] = self.figure.add_subplot(nbLine,nbCol,num+1) 124 #self.axes[num].set_title(u"Nombre d'étiquettes dans chaque partie du texte")#titre 125 else: self.axes[num] = self.figure.add_subplot(nbLine,nbCol,num+1, 126 sharex=self.axes[0],sharey=self.axes[0]) 127 valeurs = self.fm.getFreqLine(num) # ensemble des valeurs à dessiner d'un graphqiue 128 val=[] 129 for x in valeurs: val.append(x) 130 N = len(val) 131 ind = arange(N) # the x locations for the groups 132 width = 0.5 # the width of the bars 133 maxi=self.fm.getMaxGenetic() 134 #if maxi == 0: return None # toutes les valeurs de la ligne sont nulles 135 136 handles.append(self.axes[num].bar(ind, val, width, color=self.cm.getListe())) 137 self.axes[num].axhline(y=maxi/2, zorder=1) 138 yticks=[] 139 for x in xrange(maxi): #échelle des ordonnées 140 if maxi/4 == 0: yticks.append(0) ; continue 141 if x%(maxi/4)==0: yticks.append(x) 142 143 self.axes[num].set_yticks(yticks) 144 self.axes[num].set_ylabel(self.potm.abreviations(num)) 145 if num==nbLine-1: # pour le dernier seulement on affiche la légende 146 self.axes[num].set_xticks(ind+width/2) 147 self.axes[num].set_xticklabels(self.tm.getListe()) 148 else: self.axes[num].set_xticklabels([])
149 - def write_axe2(self, num,nbLine,nbCol,handles):
150 """ Fonction dessinant effectivement le num-ième graphique parmi 2 derniers, les textes totaux""" 151 if num==nbLine-2: # texte1 152 self.axes[num] = self.figure.add_subplot(nbLine,nbCol,num+1) 153 else: self.axes[num] = self.figure.add_subplot(nbLine,nbCol,num+1, 154 sharex=self.axes[nbLine-2],sharey=self.axes[nbLine-2]) # texte2 155 valeurs = self.fm.getFreqLine(num) # ensemble des valeurs à dessiner d'un graphqiue 156 val=[] 157 for x in valeurs: val.append(x) 158 N = len(val) 159 ind = arange(N) # the x locations for the groups 160 width = 0.5 # the width of the bars 161 maxi=self.fm.getMaxText() 162 163 handles.append(self.axes[num].bar(ind, val, width, color=self.cm.getListe())) 164 self.axes[num].axhline(y=maxi/2, zorder=1) 165 yticks=[] 166 for x in xrange(maxi): #échelle des ordonnées 167 if x%(maxi/4)==0: yticks.append(x) 168 self.axes[num].set_yticks(yticks) 169 self.axes[num].set_ylabel(self.potm.abreviations(num)) 170 if num==nbLine-1: # pour le dernier seulement on affiche la légende 171 self.axes[num].set_xticks(ind+width/2) 172 self.axes[num].set_xticklabels(self.tm.getListe()) 173 else: self.axes[num].set_xticklabels([])
174
175 -class FMPanelCamembert(FMPanel):
176 """ Classe représentant la part de chaque étiquette dans chaque partie du texte. 177 -> 8 camemberts"""
178 - def __init__(self, frame, fm=None):
179 """ 180 pre: isinstance(fm,MediteAppli.synthetic.FrequencyMatrix) 181 """ 182 FMPanel.__init__(self,frame,fm) 183 self.debutInitFMPanel() 184 self.dessin() 185 self.finInitFMPanel()
186 - def dessin(self):
187 fh=self.fauxHisto(self.nbLine,self.nbCol) 188 # crée les autres 189 # -2 car on ne dessine pas les BC1 et BC2 190 for i in xrange(self.fm.getNbLine()-2): 191 self.write_axe_auto(i,self.nbLine,self.nbCol,self.handles) 192 #self.figure.legend(self.handles,self.tm.getDescriptions(),'upper right', 193 # handlelen = 0.01, handletextsep = 0.01) # légende 194 self.figure.legend(fh,self.tm.getDescriptions(),'upper right', 195 handlelen = 0.01, handletextsep = 0.01) # légende
196 - def param(self):
197 self.nbLine = 2 198 self.nbCol = 4 199 self.placeFauxHisto = 8 200 self.title = u"Proportions d'étiquettes dans chaque partie du texte"
201 - def fauxHisto(self,nbLine,nbCol):
202 """ Faux histo que l'on cache avec un camembert. 203 Sert juste a avoir toutes les couleurs pour la légende car si les camemberts 204 ont des valeurs nulles, celles-ci modifient la légende """ 205 valeurs = self.fm.getFreqLine(0) # ensemble des valeurs à dessiner d'un graphqiue 206 val=[] 207 ind=[] 208 for x in valeurs: 209 val.append(1) 210 ind.append(0) 211 self.axes[0] = self.figure.add_subplot(nbLine,nbCol,self.placeFauxHisto) 212 #print len(self.cm.getListe()) 213 return self.axes[0].bar(ind, val, width=0, color=self.cm.getListe())
214
215 - def write_axe_auto(self, num,nbLine,nbCol,handles):
216 """ Dessine les axes automatiquement """ 217 self.axes[num] = self.figure.add_subplot(nbLine,nbCol,num+1) 218 #if num==0:self.axes[num].set_title(self.title)#titre 219 valeurs = self.fm.getFreqLine(num) # ensemble des valeurs à dessiner d'un graphqiue 220 val=[] 221 lab=[] 222 col=[] 223 for i in xrange(len(valeurs)):# élimine du camembert les valeurs nulles 224 if valeurs[i]>0: 225 val.append(valeurs[i]) 226 lab.append(self.tm.getListe()[i]) 227 col.append(self.cm.getListe()[i]) 228 #print val 229 handles.append(self.axes[num].pie(val, labels=lab, colors=col, 230 autopct='%1.1f%%', shadow=True)) 231 self.axes[num].set_xlabel(self.fm.potm.getItem(num))
232 - def write_axe_coordo(self,left,bottom,width,height, num,handles):
233 """ Dessine un axe avec les coordonnées left,bottom,width,height 234 num = numéro de ligne dans la matrice de données """ 235 self.axes[num] = self.figure.add_axes([left,bottom,width,height]) 236 valeurs = self.fm.getFreqLine(num) # ensemble des valeurs à dessiner d'un graphqiue 237 val=[] 238 lab=[] 239 col=[] 240 for i in xrange(len(valeurs)):# élimine du camembert les valeurs nulles 241 if valeurs[i]>0: 242 val.append(valeurs[i]) 243 lab.append(self.tm.getListe()[i]) 244 col.append(self.cm.getListe()[i]) 245 handles.append(self.axes[num].pie(val, labels=lab, colors=col, 246 autopct='%1.1f%%', shadow=True)) 247 self.axes[num].set_xlabel(self.fm.potm.getItem(num))
248 - def fauxHisto_coordo(self):
249 """ Faux histo en (0,0) largeur=0.001, hauteur=0 """ 250 valeurs = self.fm.getFreqLine(0) # ensemble des valeurs à dessiner d'un graphqiue 251 val=[] 252 ind=[] 253 for x in valeurs: 254 val.append(1) 255 ind.append(0) 256 self.axes[0] = self.figure.add_axes([0,0,0.001,0]) 257 return self.axes[0].bar(ind, val, width=0, color=self.cm.getListe())
258
259 -class FMPanelCamembert2(FMPanelCamembert):
260 """ FMPanelCamembert2 pour TagFrequencyMatrix2. 261 Suppressions et Remp1 fusionnés / Insertions et Remp2 fussionnés 262 -> 6 camemberts"""
263 - def __init__(self, frame, fm=None):
264 """ 265 pre: isinstance(fm,MediteAppli.synthetic.TagFrequencyMatrix2) 266 """ 267 FMPanelCamembert.__init__(self,frame,fm)
268 - def dessin(self):
269 t1 = t2 = sr1 = ir2 = d1 = d2 = 0.0 270 for x in self.fm.getTextLine(0): t1+=x 271 for x in self.fm.getTextLine(1): t2+=x 272 for x in self.fm.getFreqLine(0): sr1+=x 273 for x in self.fm.getFreqLine(1): ir2+=x 274 for x in self.fm.getFreqLine(2): d1+=x 275 for x in self.fm.getFreqLine(3): d2+=x 276 fh=self.fauxHisto_coordo() 277 L1 = t1+t2 278 L2 = sr1+ir2+d1+d2 279 lt1 = 0.9*t1/L1 # * 0.9 pour pouvoir ajouter la légende 280 ht1 = lt1 281 lt2 = 0.9*t2/L1 282 ht2 = lt2 283 assert(lt1+lt2==0.9,lt1+lt2) 284 lsr1 = sr1/L2 285 lir2 = ir2/L2 286 ld1 = d1/L2 287 ld2 = d2/L2 288 assert(lsr1+lir2+ld1+ld2==1,lsr1+lir2+ld1+ld2) 289 # les if >0 car si une ligne n'a que des 0 ca bug à l'affichage 290 if lt1 > 0: self.write_axe_coordo(0.01,0,lt1,ht1,4,self.handles) 291 if lt2 > 0: self.write_axe_coordo(lt1,0,lt2,ht2,5,self.handles) 292 if lsr1 > 0: self.write_axe_coordo(0.01,max(ht1,ht2),lsr1,lsr1,0,self.handles) 293 if lir2 > 0: self.write_axe_coordo(lsr1,max(ht1,ht2),lir2,lir2,1,self.handles) 294 if ld1 > 0: self.write_axe_coordo(lsr1+lir2,max(ht1,ht2),ld1,ld1,2,self.handles) 295 if ld2 > 0:self.write_axe_coordo(lsr1+lir2+ld1,max(ht1,ht2),ld2,ld2,3,self.handles) 296 self.figure.legend(fh,self.tm.getDescriptions(),(0.9,0), 297 handlelen = 0.01, handletextsep = 0.01) # légende
298 - def param(self):
299 self.nbLine = 2 300 self.nbCol = 3 301 self.placeFauxHisto = 6 302 self.title = u"Proportions d'étiquettes dans chaque partie du texte"
303
304 -class FMPanelCamembert3(FMPanelCamembert):
305 """ FMPanelCamembert3 pour TagFrequencyMatrix3. 306 Suppressions et Remp1 fusionnés / Insertions et Remp2 fussionnés 307 -> 6 camemberts"""
308 - def __init__(self, frame, fm=None):
309 """ 310 pre: isinstance(fm,MediteAppli.synthetic.TagFrequencyMatrix2) 311 """ 312 FMPanelCamembert.__init__(self,frame,fm)
313 - def dessin(self):
314 t1 = t2 = bc1 = bc2 = d1 = d2 = bcd1 = bcd2 = 0.0 315 for x in self.fm.getTextLine(0): t1 += x 316 for x in self.fm.getTextLine(1): t2 += x 317 for x in self.fm.getFreqLine(0): bc1 += x 318 for x in self.fm.getFreqLine(1): bc2 += x 319 for x in self.fm.getFreqLine(2): d1 += x 320 for x in self.fm.getFreqLine(3): d2 += x 321 for x in self.fm.getFreqLine(4): bcd1 += x 322 for x in self.fm.getFreqLine(5): bcd2 += x 323 fh=self.fauxHisto_coordo() 324 L1 = t1 + t2 # largeur totale de cette ligne 325 L2 = bc1 + bc2 + d1 + d2 + bcd1 + bcd2 326 lt1 = 0.9 * t1 / L1 # * 0.9 pour pouvoir ajouter la légende 327 ht1 = lt1 # hauteur de cette ligne 328 lt2 = 0.9 * t2 / L1 329 ht2 = lt2 330 assert str(lt1+lt2) == '0.9', lt1+lt2 331 lbc1 = bc1 / L2 # largeur de ce camembert 332 lbc2 = bc2 / L2 333 ld1 = d1 / L2 334 ld2 = d2 / L2 335 lbcd1 = bcd1 / L2 336 lbcd2 = bcd2 / L2 337 assert lbc1+lbc2+ld1+ld2+lbcd1+lbcd2 == 1, lbc1+lbc2+ld1+ld2+lbcd1+lbcd2 338 # les if >0 car si une ligne n'a que des 0 ca bug à l'affichage 339 if lt1 > 0: self.write_axe_coordo(0.01,0,lt1,ht1,6,self.handles) 340 if lt2 > 0: self.write_axe_coordo(lt1,0,lt2,ht2,7,self.handles) 341 if lbc1 > 0: self.write_axe_coordo(0.01,max(ht1,ht2),lbc1,lbc1,0,self.handles) 342 if lbc2 > 0: self.write_axe_coordo(lbc1,max(ht1,ht2),lbc2,lbc2,1,self.handles) 343 if ld1 > 0: self.write_axe_coordo(lbc1+lbc2,max(ht1,ht2),ld1,ld1,2,self.handles) 344 if ld2 > 0:self.write_axe_coordo(lbc1+lbc2+ld1,max(ht1,ht2),ld2,ld2,3,self.handles) 345 if lbcd1 > 0: self.write_axe_coordo(lbc1+lbc2+ld1+ld2,max(ht1,ht2),lbcd1,lbcd1,4,self.handles) 346 if lbcd2 > 0: self.write_axe_coordo(lbc1+lbc2+ld1+ld2+lbcd1,max(ht1,ht2),lbcd2,lbcd2,5,self.handles) 347 self.figure.legend(fh,self.tm.getDescriptions(),(0.9,0), 348 handlelen = 0.01, handletextsep = 0.01) # légende
349 - def param(self):
350 self.nbLine = 2 351 self.nbCol = 4 352 self.placeFauxHisto = 6 353 self.title = u"Proportions d'étiquettes dans chaque partie du texte"
354
355 -class FMPanelCamembert4(FMPanelCamembert):
356 """ FMPanelCamembert4 pour TextFrequencyMatrix 357 Seulement 2 camemberts, un pour chaque texte"""
358 - def __init__(self, frame, fm=None):
359 """ 360 pre: isinstance(fm,MediteAppli.synthetic.TextFrequencyMatrix) 361 """ 362 FMPanel.__init__(self,frame,fm) 363 #FMPanelCamembert.__init__(self,frame,fm) 364 tot1 = tot2 = 0.0 365 for x in self.fm.getFreqLine(0): tot1+=x 366 for x in self.fm.getFreqLine(1): tot2+=x 367 self.taille={0:tot1/(tot1+tot2), 1:tot2/(tot1+tot2)} 368 #print self.taille 369 self.cm = ColorManager(2) 370 self.debutInitFMPanel() 371 self.dessin() 372 self.finInitFMPanel()
373
374 - def param(self):
375 self.nbLine = 1 376 self.nbCol = 2 377 self.placeFauxHisto = 2 378 self.title = u"(Supp+Remp1)/BC1 et (Ins+Remp2)/BC2"
379 - def dessin(self):
380 fh=self.fauxHisto_coordo() 381 self.write_axe_coordo(0.01,0,self.taille[0],self.taille[0],0,self.handles) 382 self.write_axe_coordo(self.taille[0],0,self.taille[1],self.taille[1],1,self.handles) 383 self.figure.legend(fh,self.tm.getDescriptions(),'upper right', 384 handlelen = 0.01, handletextsep = 0.01) # légende
385 386 387 388 if __name__=='__main__':
389 - class App(wx.App):
390 """ Application de test """
391 - def OnInit(self):
392 """Create the main window and insert the custom frame""" 393 frame = wx.Frame(None,-1) 394 #panel = FMPanelHisto(frame,self.fm()) 395 #panel = FMPanelCamembert2(frame,self.fm2()) 396 #panel = FMPanelCamembert4(frame,self.tm()) 397 panel = FMPanelCamembert3(frame,self.fm3()) 398 frame.Show(True) 399 return True
400 - def fm(self):
401 """ Renvoie une TagFrequencyMatrix de test """ 402 self.tm = MediteAppli.synthetic.TagManager() 403 self.potm = MediteAppli.synthetic.PartOfTextManager() 404 l = self.tm.getNbItems() 405 freqGeneticModifs = Numeric.array( 406 [[0 for i in xrange(l)], 407 [1 for i in xrange(l)], 408 [2 for i in xrange(l)], 409 [3 for i in xrange(l)], 410 [4 for i in xrange(l)], 411 [5 for i in xrange(l)], 412 [6 for i in xrange(l)], 413 [7 for i in xrange(l)]]) 414 freqTexts = Numeric.array( 415 [[8 for i in xrange(l)], 416 [9 for i in xrange(l)]]) 417 fm = MediteAppli.synthetic.TagFrequencyMatrix(freqGeneticModifs,freqTexts) 418 fm.setRelation([0,2,4,6],0) 419 fm.setRelation([1,3,5,7],1) 420 return fm
421 - def fm2(self):
423 - def fm3(self):
425 - def tm(self):
426 import Donnees.resultatAppli 427 d = Donnees.resultatAppli.Resultat( [(100,133)], [(0,10)], [], [], 50, 428 "01234567890123456789012345678901234567890123456789"+"01234567890123456789012345678901234567890123456789"+"01234567890123456789012345678901234567890123456789"+"01234567890123456789012345678901234567890123456789" 429 ,[(10,50),(133,200)], []) 430 tm = MediteAppli.synthetic.TextFrequencyMatrix(d) 431 #print tm.getFreqLine(0) 432 #print tm.getFreqLine(1) 433 return tm
434 435 try: 436 app = App(0) 437 app.MainLoop() 438 except Exception,e1: 439 import traceback,sys 440 traceback.print_exc() 441 sys.stderr.flush() 442