Blaz Zupan avatar Blaz Zupan committed 9be542c

no message

Comments (0)

Files changed (2)

OWDisplayProfiles.py

         # GRAPH TAB
         GraphTab = QVGroupBox(self)
 
+        ## display options
+        displayOptBox = QVButtonGroup("Display", GraphTab)
+        displayOptButtons = ['Majority Class', 'Majority Class Probability', 'Target Class Probability', 'Number of Instances']
+        OWGUI.checkOnly(displayOptBox, self, 'Expression Profiles', 'ShowSingleProfiles', tooltip='', callback=self.updateShowSingleProfiles)
+        OWGUI.checkOnly(displayOptBox, self, 'Box Plot', 'ShowAverageProfile', tooltip='', callback=self.updateShowAverageProfile)
+
         ## class selection (classQLB)
         self.classQVGB = QVGroupBox(GraphTab)
         self.classQVGB.setTitle("Classes")
         self.classQLB = QListBox(self.classQVGB)
         self.classQLB.setSelectionMode(QListBox.Multi)
-        self.unselectAllClassedQLB = QPushButton("(Un)select all", self.classQVGB)
+        self.unselectAllClassedQLB = QPushButton("(Un)Select All", self.classQVGB)
         self.connect(self.unselectAllClassedQLB, SIGNAL("clicked()"), self.SUAclassQLB)
         self.connect(self.classQLB, SIGNAL("selectionChanged()"), self.classSelectionChange)
 
 ##        self.connect(self.showAverageQLB, SIGNAL("toggled(bool)"), self.updateShowAverageProfile)
 ##        self.connect(self.showSingleQLB, SIGNAL("toggled(bool)"), self.updateShowSingleProfiles)
 
-        ## display options
-        displayOptBox = QVButtonGroup("Display", GraphTab)
-        displayOptButtons = ['Majority Class', 'Majority Class Probability', 'Target Class Probability', 'Number of Instances']
-        OWGUI.checkOnly(displayOptBox, self, 'Profiles', 'ShowSingleProfiles', tooltip='', callback=self.updateShowSingleProfiles)
-        OWGUI.checkOnly(displayOptBox, self, 'Box Plot', 'ShowAverageProfile', tooltip='', callback=self.updateShowAverageProfile)
 
         self.tabs.insertTab(GraphTab, "Graph")
 
             self.calcGraph()
             ## update graphics
             ## classQLB
-            self.classQLB.show()
+            self.classQVGB.show()
             classValues = self.MAdata.domain.classVar.values.native()
             for cn in range(len(classValues)):
                 self.classQLB.insertItem(ColorPixmap(self.classColor[cn]), classValues[cn])
             self.classQLB.selectAll(1)  ##or: if numberOfClasses > 0: self.classQLB.setSelected(0, 1)
 
             if self.MAnoclass:
-                self.classQLB.hide()
+                self.classQVGB.hide()
         else:
             self.classColor = None
             self.classBrighterColor = None
     def data(self, MAdata):
         if not MAdata:
             self.graph.hide()
-            self.classQLB.hide()
+            self.classQVGB.hide()
             return
         ## if there is no class attribute, create a dummy one
         if MAdata.domain.classVar == None:
                     "ShowAnnotation", "LegendOnTop", "LegendOnBottom", "ShowAverageStripe", "ShowGroupLabel",
                     "MaintainArrayHeight",
                     'BShowballoon', 'BShowColumnID', 'BShowSpotIndex', 'BShowAnnotation', 'BShowGeneExpression',
-                    "BSpotVar", "BAnnotationVar",
+                    "BSpotVar", "ShowGeneAnnotations", "BAnnotationVar",
                     "CurrentPalette"]
 
     def __init__(self, parent=None, name='OWHeatMap'):
         OWWidget.__init__(self, parent, name, 'Microarray Heat Map', FALSE, FALSE) 
         
         self.inputs = [("Examples", ExampleTable, self.dataset, 1)]
-        self.outputs = [("Examples", ExampleTable)]
+        self.outputs = [("Examples", ExampleTable), ("Classified Examples", ExampleTableWithClass)]
 
         #set default settings
         self.CellWidth = 3; self.CellHeight = 3
         self.ShowGroupLabel = 1        # show class names in case of classified data?
         self.ShowAverageStripe = 1     # show the stripe with the evarage
         self.MaintainArrayHeight = 1   # adjust cell height while changing the merge factor
-        self.BShowballoon = 1           # balloon help
+        self.BShowballoon = 1          # balloon help
+        self.ShowGeneAnnotations = 1   # show annotations for genes
         self.BShowColumnID = 1; self.BShowSpotIndex = 1; self.BShowAnnotation = 1; self.BShowGeneExpression = 1
         self.BSpotVar = None; self.BAnnotationVar = None
         self.setColorPalette()
         
         self.loadSettings()
         self.data = None
-        self.maxHSize = 10; self.maxVSize = 10
+        self.maxHSize = 15; self.maxVSize = 15
 
         # GUI definition
         self.tabs = QTabWidget(self.controlArea, 'tabWidget')
         colorItems = [self.createColorStripe(i) for i in range(len(self.ColorPalettes))]
         OWGUI.comboBox(settingsTab, self, "CurrentPalette", box="Colors", items=colorItems, tooltip=None, callback=self.setColor)
 
-        box = QVButtonGroup("Annotations", settingsTab)
-        OWGUI.checkOnly(box, self, 'Legend (top)', 'LegendOnTop', callback=self.drawHeatMap)
-        OWGUI.checkOnly(box, self, 'Stripes with averages', 'ShowAverageStripe', callback=self.drawHeatMap)
         
         self.tabs.insertTab(settingsTab, "Settings")
 
 
         # INFO TAB
         tab = QVGroupBox(self)
+
+        box = QVButtonGroup("Graph Annotation", tab)
+        OWGUI.checkOnly(box, self, 'Legend (top)', 'LegendOnTop', callback=self.drawHeatMap)
+        OWGUI.checkOnly(box, self, 'Stripes with averages', 'ShowAverageStripe', callback=self.drawHeatMap)
+        OWGUI.checkOnly(box, self, 'Gene annotations', 'ShowGeneAnnotations', callback=self.drawHeatMap)
+        self.annotationCombo = OWGUI.comboBox(box, self, "BAnnotationVar", items=[], callback=self.drawHeatMap)
+
         box = QVButtonGroup("Balloon", tab)
         OWGUI.checkOnly(box, self, "Show balloon", 'BShowballoon', callback=lambda: self.balloonInfoBox.setDisabled(not self.BShowballoon))
         box = QVButtonGroup("Balloon Info", tab)
         OWGUI.checkOnly(box, self, "Spot Index", 'BShowSpotIndex', callback=lambda: self.spotCombo.setDisabled(not self.BShowSpotIndex))
         self.spotCombo = OWGUI.comboBox(box, self, "BSpotVar", items=[])
         OWGUI.checkOnly(box, self, "Gene expression", 'BShowGeneExpression')
-        OWGUI.checkOnly(box, self, "Annotation", 'BShowAnnotation', callback=lambda: self.annotationCombo.setDisabled(not self.BShowAnnotation))
-        self.annotationCombo = OWGUI.comboBox(box, self, "BAnnotationVar", items=[])
+        OWGUI.checkOnly(box, self, "Annotation", 'BShowAnnotation')
         self.balloonInfoBox = box
         self.tabs.insertTab(tab, "Info")
         
-        self.resize(400,400)
+        self.resize(700,400)
 
         # canvas with microarray
         self.layout = QVBoxLayout(self.mainArea)
         if not data:
             return
         self.data = data
-
-        # this is only to check, once bug is removed: remove
-        bs = orange.DomainBasicAttrStat(self.data)
-        minVal = min([bs[x].min for x in self.data.domain.attributes])
-        maxVal = max([bs[x].max for x in self.data.domain.attributes])
-        print 'mmm', minVal, maxVal
-##        self.sliderCutLow.setRange(minVal, 0, 0.1)
-##        self.sliderCutHigh.setRange(0.0001, maxVal, 0.1)
-##        if minVal > self.CutLow:
-##            self.CutLow = minValue
-##        if maxVal < self.CutLow:
-##            self.CutLow = maxValue
-##        self.sliderCutLow.setValue(self.CutLow)
-##        self.sliderCutHigh.setValue(self.CutHigh)
-        
+        self.setMetaCombos() # set the two combo widgets according to the data
         self.heatmapconstructor = orange.HeatmapConstructor(self.data)
         self.createHeatMap()
-        self.setMetaCombos() # set the two combo widgets according to the data
 
     # send out the data for selected rows, rows = [(group, from, to), ...]
     def sendData(self, rows):
         for (g,s,e) in rows:
             hm = self.heatmaps[g]
             ex += hm.examples[hm.exampleIndices[s] : hm.exampleIndices[e+1]]
-        # ex = hm.examples[hm.exampleIndices[row] : hm.exampleIndices[row+1]]
-        d = orange.ExampleTable(self.data.domain, ex)
-        self.send("Examples", d)
+
+        # the following code constructs a new data set, such that only
+        # class values that are used are present
+        cl = self.data.domain.classVar
+        if cl:
+            valPresent = [None] * len(cl.values)
+            for d in ex:
+                c = int(d.getclass())
+                if not valPresent[c]: valPresent[c] = c
+            values = [cl.values[i] for i in filter(lambda x:x<>None, valPresent)]
+
+            if len(values)>1: # more than one class value used
+                newClass = orange.EnumVariable(name=cl.name, values=values, getValueFrom=lambda e, v: e.getclass())
+                domain = orange.Domain(self.data.domain.attributes, newClass)
+            else:
+                domain = orange.Domain(self.data.domain.attributes, 0)
+            metas = self.data.domain.getmetas()
+            for key in metas:
+                domain.addmeta(key, metas[key])
+            selectedData = orange.ExampleTable(domain, ex)
+            if len(values)>1:
+                self.send("Classified Examples", selectedData)
+        else:
+            selectedData = orange.ExampleTable(self.data.domain, ex)
+        self.send("Examples", selectedData)
 
     ##########################################################################
     # callback functions
         t.show()
         return y + t.boundingRect().height() + 1
 
+    def drawGeneAnnotation(self, x, y, group):
+##        print 'hhh', len(self.heatmaps[group].exampleIndices)
+##        for i in self.heatmaps[group].exampleIndices:
+##            print i
+
+        # determine the appropriate font width for annotation
+        # this part is ugly, we need to do it computationally
+        font = QFont()
+        dummy = QCanvasText("dummy", self.canvas)
+        last = 2; offset = 0
+        for fsize in range(2,9):
+            font.setPointSize(fsize)
+            dummy.setFont(font)
+            if dummy.boundingRect().height() > self.CellHeight:
+                break
+            offset = (self.CellHeight - dummy.boundingRect().height())/2
+            last = fsize
+        font.setPointSize(last)
+        y += offset
+
+        # annotate
+        hm = self.heatmaps[group]
+        annotationVar = self.meta[self.BAnnotationVar]
+        for (row, indices) in enumerate(hm.exampleIndices[:-1]):
+            t = QCanvasText(str(hm.examples[hm.exampleIndices[row]][annotationVar]), self.canvas)
+            t.setFont(font)
+            t.setX(x); t.setY(y)
+            t.show()
+            y += self.CellHeight
+
     def drawHeatMap(self):
         lo = self.CutEnabled and self.CutLow   or self.lowerBound
         hi = self.CutEnabled and self.CutHigh  or self.upperBound
                 avg, avgWidth, avgHeight = self.heatmaps[g].getAverages(c_averageStripeWidth, int(self.CellHeight), lo, hi, self.Gamma)
                 ImageItem(avg, self.canvas, avgWidth, avgHeight, palette, x=c_offsetX, y=y)
             self.imgEnd.append(y+self.heights[g]-1)
+
+            if self.ShowGeneAnnotations and self.CellHeight>4:
+                self.drawGeneAnnotation(x+self.imageWidth+c_offsetX/2, y, g)
             y += self.heights[g] + c_spaceY
+        x += self.imageWidth
 
-##        for i in range(len(self.imgStart)):
-##            l = QCanvasLine(self.canvas)
-##            l.setPoints(2, self.imgStart[i], 2, self.imgEnd[i])
-##            print 'line %d->%d ' % (self.imgStart[i], self.imgEnd[i]),
-##            l.show()
-##        print
         self.selection.redraw()        
         self.canvas.update()
         
         merge = min(self.Merge, float(len(self.data)))
         squeeze = 1. / merge
         self.heatmaps, self.lowerBound, self.upperBound = self.heatmapconstructor(squeeze)
-        print 'bbb', self.lowerBound, self.upperBound
 
         self.sliderCutLow.setRange(self.lowerBound, 0, 0.1)
         self.sliderCutHigh.setRange(1e-10, self.upperBound, 0.1)
         self.CutHigh = min(self.CutHigh, self.upperBound)
         self.sliderCutLow.setValue(self.CutLow)
         self.sliderCutHigh.setValue(self.CutHigh)
-        
+
+        self.selection.remove()
+
         self.drawHeatMap()
 
 ##################################################################################################
             col, row = int(x / self.dx), int(y / self.dy)
             # hm.getCellIntensity(row, col), hm.getRowIntensity(row)
             ex = hm.examples[hm.exampleIndices[row] : hm.exampleIndices[row+1]]
+            #print 'xxx', hm.exampleIndices[row], hm.exampleIndices[row+1]
             self.selector.setX(item.x()+col*self.dx-v_sel_width+1)
             self.selector.setY(item.y()+row*self.dy-v_sel_width+1)
             self.selector.show()
     def remove(self):
         for r in self.squares:
             r.setCanvas(None)
-        self.squares = []; self.rows
+        self.squares = []; self.rows = []
 
     # starts the selection, called after the first click
     def start(self, p1, p2, add=False):
     a.setMainWidget(ow)
 
 ##    data = orange.ExampleTable('wt-large')
-    d = orange.ExampleTable('wt')
-##    d = orange.ExampleTable('wtclassed')
+##    d = orange.ExampleTable('wt')
+    d = orange.ExampleTable('wtclassed')
     ow.dataset(d)
     ow.show()
     a.exec_loop()
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for ProjectModifiedEvent.java.
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.