source: orange-bioinformatics/_bioinformatics/widgets/OWVulcanoPlot.py @ 1636:10d234fdadb9

Revision 1636:10d234fdadb9, 28.3 KB checked in by mitar, 2 years ago (diff)

Restructuring because we will not be using namespaces.

Line 
1"""
2<name>Vulcano Plot</name>
3<description>Plots fold change vs. p-value.)</description>
4<priority>1020</priority>
5<contact>Ales Erjavec (ales.erjavec@fri.uni-lj.si)</contact>
6<icon>icons/VulcanoPlot.png</icon>
7"""
8
9from __future__ import absolute_import
10
11import itertools
12from operator import add
13from collections import defaultdict
14from math import log
15
16import numpy
17
18import orange
19from statc import mean, ttest_ind
20
21from Orange.orng.orngDataCaching import data_hints
22from Orange.OrangeWidgets.OWToolbars import ZoomSelectToolbar
23from Orange.OrangeWidgets.OWWidget import *
24from Orange.OrangeWidgets.OWGraph import *
25from Orange.OrangeWidgets import OWGUI
26
27from .. import obiExpression
28from ..obiGEO import transpose
29
30class GraphSelections(QObject):
31    """ Selection manager using a union of rectangle areas
32    """
33    def __init__(self, parent):
34        QObject.__init__(self, parent)
35        self.selection = []
36       
37    def getPos(self, event):
38        graph = self.parent()
39        pos = graph.canvas().mapFrom(graph, event.pos())
40        x = graph.invTransform(QwtPlot.xBottom, pos.x())
41        y = graph.invTransform(QwtPlot.yLeft, pos.y())
42        return QPointF(x, y)
43       
44    def start(self, event):
45        pos = self.getPos(event)
46        if event.modifiers() & Qt.ControlModifier:
47            self.selection.append((pos, pos))
48        else:
49            self.selection = [(pos, pos)]
50        self.emit(SIGNAL("selectionGeometryChanged()"))
51   
52    def update(self, event):
53        pos = self.getPos(event)
54        self.selection[-1] = self.selection[-1][:-1] + (pos,)
55        self.emit(SIGNAL("selectionGeometryChanged()"))
56   
57    def end(self, event):
58        self.update(event)
59       
60    def testSelection(self, data):
61        if len(data) == 0:
62            return []
63        data = numpy.asarray(data)
64        region = QPainterPath()
65        for p1, p2 in self.selection:
66            region.addRect(QRectF(p1, p2).normalized())
67        def test(point):
68            return region.contains(QPointF(point[0], point[1]))
69        test = numpy.apply_along_axis(test, 1, data)
70        return test
71       
72class SymetricSelections(GraphSelections):
73    """ Selection manager using two symmetric areas extending to 'infinity' 
74    """
75    def __init__(self, parent, x=3, y=3):
76        GraphSelections.__init__(self, parent)
77        max = 100000
78        self.selection = [(QPointF(-max, max), QPointF(-x, y)), (QPointF(max, max), QPointF(x, y))]
79        self.updateAxes = None
80       
81    def updateSelection(self, axes, pos):
82        if axes == QwtPlot.xBottom or axes == -1:
83            self.selection[0][1].setX(-abs(pos.x()))
84            self.selection[1][1].setX(abs(pos.x()))
85        if axes == QwtPlot.yLeft or axes == -1:
86            self.selection[0][1].setY(pos.y())
87            self.selection[1][1].setY(pos.y())
88           
89        self.emit(SIGNAL("selectionGeometryChanged()"))
90       
91    def getAxesAndPos(self, event):
92        graph = self.parent()
93        pos = graph.canvas().mapFrom(graph, event.pos())
94        x = graph.invTransform(QwtPlot.xBottom, pos.x())
95        y = graph.invTransform(QwtPlot.yLeft, pos.y())
96       
97        offset = 3
98        dx = abs(graph.invTransform(QwtPlot.xBottom, pos.x() + offset) - x)
99        dy = abs(graph.invTransform(QwtPlot.yLeft, pos.y() + offset) - y)
100       
101        x = abs(x)
102       
103        cx = self.selection[1][1].x()
104        cy = self.selection[1][1].y()
105
106        bottom = QRectF(QPointF(cx, cy), QPointF(graph.maxX, cy)).adjusted(-dx, dy, dx, -dy).normalized()
107        left = QRectF(QPointF(cx, graph.maxY), QPointF(cx, cy)).adjusted(-dx, dy, dx, -dy).normalized()
108       
109        if bottom.contains(QPointF(x, y)) or bottom.contains(QPointF(-x, y)):
110            axes = QwtPlot.yLeft
111        elif left.contains(QPointF(x, y)) or left.contains(QPointF(-x, y)):
112            axes = QwtPlot.xBottom
113        else:
114            axes = -1
115        return axes, QPointF(x, y)
116       
117    def start(self, event):
118        axes, pos = self.getAxesAndPos(event)
119        self.updateAxes = axes
120        self.updateSelection(axes, pos)
121       
122    def update(self, event):
123        _, pos = self.getAxesAndPos(event)
124        self.updateSelection(self.updateAxes, pos)
125   
126    def end(self, event):
127        self.update(event)
128        self.updateAxes = None
129       
130    def testSelection(self, data):
131        if len(data) == 0:
132            return []
133        data = numpy.asarray(data)
134        cutoffX = self.selection[1][1].x()
135        cutoffY = self.selection[1][1].y()
136        return (numpy.abs(data[:, 0]) >= cutoffX) & (data[:, 1] >= cutoffY)
137   
138from Orange.OrangeWidgets.OWItemModels import PyListModel
139
140def item_selection(indices, model, selection=None, column=0):
141    """ Create an QItemSelection for indices in model.
142    """
143    if selection is None:
144        selection = QItemSelection()
145       
146    for i in indices:
147        selection.select(model.index(i, column))
148    return selection
149
150
151class LabelSelectionWidget(QWidget):
152    """ A widget for selection of label values.
153    """
154    def __init__(self, parent=None):
155        QWidget.__init__(self, parent)
156        self._values_model = PyListModel([], parent=self)
157        layout = QVBoxLayout()
158        layout.setContentsMargins(0, 0, 0, 0)
159        def group_box(title):
160            box = QGroupBox(title)
161            box.setFlat(True)
162            lay = QVBoxLayout()
163            lay.setContentsMargins(0, 0, 0, 0)
164            box.setLayout(lay)
165            return box
166       
167        self.labels_combo = QComboBox()
168        self.values_view = QListView()
169        self.values_view.setSelectionMode(QListView.ExtendedSelection)
170        self.values_view.setModel(self._values_model)
171       
172       
173        self.connect(self.labels_combo, SIGNAL("activated(int)"),
174                     self.on_label_activated)
175       
176        self.connect(self.values_view.selectionModel(),
177                     SIGNAL("selectionChanged(QItemSelection, QItemSelection)"),
178                     self.on_values_selection)
179       
180        l_box = group_box("Label")
181        v_box = group_box("Values")
182       
183        l_box.layout().addWidget(self.labels_combo)
184        v_box.layout().addWidget(self.values_view)
185       
186        layout.addWidget(l_box)
187        layout.addWidget(v_box)
188       
189        self.setLayout(layout)
190       
191        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
192       
193        self._block_selection_emit = False
194       
195        self.labels = []
196        self.set_labels([])
197       
198    def clear(self):
199        self.labels_combo.clear()
200#        self.values_view.clear()
201        self._values_model[:] = []
202        self.labels = []
203       
204    def set_labels(self, labels):
205        """ Set the labels to display.
206        """
207        self.clear()
208        if isinstance(labels, dict):
209            labels = labels.items()
210           
211        self.labels = labels
212        for label, values in labels:
213            self.labels_combo.addItem(label)
214           
215        if labels:
216            self.set_current_label(0)
217#            self.labels_combo.setCurrentIndex(0)
218           
219    def set_selection(self, label, values):
220        """ Set the selection to label and values
221        """
222        if isinstance(label, basestring):
223            labels = [l for l, _ in self.labels]
224            index = labels.index(label) if label in labels else -1
225        else:
226            index = label
227           
228        if index >= 0:
229            if index != self.labels_combo.currentIndex():
230                self.set_current_label(index)
231               
232            all_values = list(self._values_model)
233            values = [v for v in values if v in all_values]
234            selection = QItemSelection()
235            for i, v in enumerate(self._values_model):
236                if v in values:
237                    index = self._values_model.index(i, 0)
238                    selection.select(index, index)
239            self.values_view.selectionModel().select(selection,  QItemSelectionModel.ClearAndSelect)
240        else:
241            self.values_view.selectionModel().clear()
242           
243    def set_current_label(self, index):
244        """ Set the current label
245        """
246        self.labels_combo.setCurrentIndex(index)
247        label, values = self.labels[index]
248        # Block selection changed
249        with self._blocked_signals():
250            self._values_model[:] = values
251       
252    def on_label_activated(self, index):
253        label, values = self.labels[index]
254        with self._blocked_signals():
255            self._values_model[:] = values
256        self.emit(SIGNAL("label_activated()"))
257        self.emit(SIGNAL("label_activated(int)"), index)
258   
259    def on_values_selection(self, selected, deselected):
260        label, values = self.current_selection()
261        self.emit(SIGNAL("selection_changed()"))
262        self.emit(SIGNAL("selection_changed(PyQt_PyObject, PyQt_PyObject)"),
263                  label, values)
264       
265    def selection_indexes(self):
266        """ Return the values selection indices.
267        """
268        selection = self.values_view.selectionModel().selection()
269        indexes = selection.indexes()
270        return sorted(set([i.row() for i in indexes]))       
271       
272    def current_selection(self):
273        """ Return the current label and selected values.
274        """
275        i = self.labels_combo.currentIndex()
276        label, all_values = self.labels[i]
277        values = [all_values[i] for i in self.selection_indexes()]
278        return label, values
279   
280    def _blocked_signals(self):
281        """ Return a context handler blocking all emited signals from this
282        object.
283         
284        """
285        class block(object):
286            def __enter__(blocker):
287                self.blockSignals(True)
288            def __exit__(blocker, *args):
289                self.blockSignals(False)
290                return False
291        return block()
292               
293    def sizeHint(self):
294        return QSize(100, 200)
295           
296       
297class VulcanoGraph(OWGraph):
298    def __init__(self, master, *args, **kwargs):
299        OWGraph.__init__(self, *args, **kwargs)
300        self.master = master
301        self.cutoffX = 2.0
302        self.cutoffY = 3.0
303        self.maxX, self.maxY = 10, 10
304        self.symbolSize = 5
305        self.symetricSelections = True
306       
307        self.selectedCurve = self.addCurve("", brushColor=Qt.red)
308        self.unselectedCurve = self.addCurve("", brushColor=Qt.blue)
309       
310        self.plotValues = {}
311
312        self.setAxisAutoScale(QwtPlot.xBottom)
313        self.setAxisAutoScale(QwtPlot.yLeft)
314       
315        self.reselect(replot=False)
316       
317    def setSelection(self, selection):
318        self.selection = selection
319        self.connect(self.selection, SIGNAL("selectionGeometryChanged()"), self.onSelectionChanged)
320        if self.plotValues:
321            self.updateSelectionArea()
322           
323    def onSelectionChanged(self):
324        self.replot_()
325        self.emit(SIGNAL("selectionChanged()"))
326       
327    def splitSelected(self):
328        test =  self.selection.testSelection(self.plotData)
329        return (self.plotData[numpy.nonzero(test)], self.plotData[numpy.nonzero(~test)])
330   
331    def setPlotValues(self, values):
332        self.plotValues = values
333        self.plotData = numpy.array(values.values())
334        self.replot_(setScale=True)
335
336    def createSelectionRectCurve(self, p1, p2):
337        curve = self.addCurve("selection", style=QwtPlotCurve.Lines, penColor=Qt.red, symbol=QwtSymbol.NoSymbol)
338        curve.setData([p1.x(), p2.x(), p2.x(), p1.x(), p1.x()], [p1.y(), p1.y(), p2.y(), p2.y(), p1.y()])
339       
340    def items(self, title=None):
341        for item in self.itemList():
342            if str(item.title().text()) == title:
343                yield item
344       
345    def updateSelectionArea(self):
346        for c in self.items(title="selection"):
347            c.detach()
348        for p1, p2 in self.selection.selection:
349            self.createSelectionRectCurve(p1, p2)
350
351    def replot_(self, setScale=False):
352        if self.plotValues:
353            data = self.plotData
354            self.maxX = numpy.max(numpy.abs(data[:,0]))
355            self.maxY = numpy.max(data[:, 1])
356            if setScale:
357                self.setAxisScale(QwtPlot.xBottom, -self.maxX, self.maxX)
358                self.setAxisScale(QwtPlot.yLeft, 0.0, self.maxY)
359           
360            selected, unselected = self.splitSelected()
361           
362            self.selectedCurve.setData(selected[:,0], selected[:,1])
363            self.selectedCurve.setBrush(QBrush(Qt.blue))
364            self.unselectedCurve.setData(unselected[:, 0], unselected[:, 1])
365            self.updateSelectionArea()
366            self.master.infoLabel2.setText("%i selected genes" % len(selected))
367        else:
368            for curve in [self.selectedCurve, self.unselectedCurve]:
369                curve.setData([],[])
370            self.master.infoLabel2.setText("0 selected genes")
371        self.replot()
372
373    def updateCutoff(self, axis, pos):
374        if axis == QwtPlot.xBottom:
375            self.cutoffX = abs(self.invTransform(axis, self.canvas().mapFrom(self, pos).x()))
376        elif axis == QwtPlot.yLeft:
377            self.cutoffY = self.invTransform(axis, self.canvas().mapFrom(self, pos).y())
378        else:
379            self.cutoffX = abs(self.invTransform(QwtPlot.xBottom, self.canvas().mapFrom(self, pos).x()))
380            self.cutoffY = self.invTransform(QwtPlot.yLeft, self.canvas().mapFrom(self, pos).y())
381        self.replot_()
382
383    def mousePressEvent(self, event):
384        if self.state == SELECT:
385            if event.button() == Qt.LeftButton:
386                self.selection.start(event)
387        else:
388            OWGraph.mousePressEvent(self, event)
389
390    def mouseMoveEvent(self, event):
391        if self.state == SELECT:
392            if event.buttons() & Qt.LeftButton:
393                self.selection.update(event)
394            if isinstance(self.selection, SymetricSelections):
395                axes, pos = self.selection.getAxesAndPos(event)
396                cursors = {QwtPlot.xBottom: Qt.SizeHorCursor,
397                           QwtPlot.yLeft: Qt.SizeVerCursor}
398                self.canvas().setCursor(cursors.get(axes, self._cursor))
399        else:
400            OWGraph.mouseMoveEvent(self, event)
401
402    def mouseReleaseEvent(self, event):
403        if self.state == SELECT:
404            if event.button() == Qt.LeftButton:
405                self.selection.end(event)
406        else:
407            OWGraph.mouseReleaseEvent(self, event)
408           
409    def reselect(self, replot=True):
410        if self.symetricSelections:
411            self.setSelection(SymetricSelections(self, x=self.maxX*0.80, y=self.maxY*0.80))
412        else:
413            self.setSelection(GraphSelections(self))
414            self.canvas().setCursor(self._cursor)
415        if replot:
416            self.replot_()
417
418    def updateSymbolSize(self):
419        def setSize(curve, size):
420            symbol = curve.symbol()
421            symbol.setSize(size)
422            if QWT_VERSION_STR >= "5.2":
423                curve.setSymbol(symbol)
424        setSize(self.selectedCurve, self.symbolSize)
425        setSize(self.unselectedCurve, self.symbolSize)
426        self.replot()
427       
428from .OWGenotypeDistances import SetContextHandler
429from .OWFeatureSelection import disable_controls
430
431class OWVulcanoPlot(OWWidget):
432    settingsList = ["graph.cutoffX", "graph.cutoffY", "graph.symbolSize", "graph.symetricSelections", "showXTitle", "showYTitle"]
433    contextHandlers = {"":DomainContextHandler("", [ContextField("graph.symbolSize"), ContextField("graph.cutoffX"),
434                                                    ContextField("graph.cutoffY")]),
435                       "targets": SetContextHandler("targets")}
436    def __init__(self, parent=None, signalManager=None, name="Vulcano Plot"):
437        OWWidget.__init__(self, parent, signalManager, name, wantGraph=True)
438       
439        self.inputs = [("Examples", ExampleTable, self.setData)]
440        self.outputs =[("Examples with selected attributes", ExampleTable)]
441
442        self.genes_in_columns = False
443
444        self.showXTitle = True
445        self.showYTitle = True
446
447        self.auto_commit = False
448        self.selection_changed_flag = False
449        self.target_group = None, []
450        self.label_selections = []
451
452        self.graph = VulcanoGraph(self)
453        self.connect(self.graph, SIGNAL("selectionChanged()"), self.on_selection_changed)
454        self.mainArea.layout().addWidget(self.graph)
455       
456        self.loadSettings()
457       
458        ## GUI
459        box = OWGUI.widgetBox(self.controlArea, "Info")
460        self.infoLabel = OWGUI.label(box, self, "")
461        self.infoLabel.setText("No data on input")
462        self.infoLabel2 = OWGUI.label(box, self, "")
463        self.infoLabel2.setText("0 selected genes")
464       
465        box = OWGUI.widgetBox(self.controlArea, "Target Labels")
466       
467        self.target_widget = LabelSelectionWidget(self)
468        self.connect(self.target_widget,
469                     SIGNAL("selection_changed(PyQt_PyObject, PyQt_PyObject)"),
470                     self.on_target_changed)
471        self.connect(self.target_widget,
472                     SIGNAL("label_activated(int)"),
473                     self.on_label_activated)
474       
475        box.layout().addWidget(self.target_widget)
476       
477        self.genesInColumnsCheck = OWGUI.checkBox(box, self, "genes_in_columns",
478                                    "Genes in columns", 
479                                    callback=[self.init_from_data, self.plot])
480
481        box = OWGUI.widgetBox(self.controlArea, "Settings")
482        OWGUI.hSlider(box, self, "graph.symbolSize", label="Symbol size:   ", minValue=2, maxValue=20, step=1, callback = self.graph.updateSymbolSize)
483        OWGUI.checkBox(box, self, "showXTitle", "X axis title", callback=self.setAxesTitles)
484        OWGUI.checkBox(box, self, "showYTitle", "Y axis title", callback=self.setAxesTitles)
485       
486        toolbar = ZoomSelectToolbar(self, self.controlArea, self.graph, buttons=[ZoomSelectToolbar.IconSelect, ZoomSelectToolbar.IconZoom, ZoomSelectToolbar.IconPan])
487       
488        top_layout = toolbar.layout()
489        top_layout.setDirection(QBoxLayout.TopToBottom)
490        button_layotu = QHBoxLayout()
491        top_layout.insertLayout(0, button_layotu)
492       
493        for i in range(1, top_layout.count()):
494            item = top_layout.itemAt(1)
495            top_layout.removeItem(item)
496            button_layotu.addItem(item)
497       
498        OWGUI.checkBox(toolbar, self, "graph.symetricSelections", "Symetric selection", callback=self.graph.reselect)
499
500        box = OWGUI.widgetBox(self.controlArea, "Commit")
501        b = OWGUI.button(box, self, "Commit", callback=self.commit, default=True)
502        cb = OWGUI.checkBox(box, self, "auto_commit", "Commit automatically")
503        OWGUI.setStopper(self, b, cb, "selection_changed_flag", self.commit_if)
504
505        self.connect(self.graphButton, SIGNAL("clicked()"), self.graph.saveToFile)
506       
507        OWGUI.rubber(self.controlArea)
508
509        self.data = None
510        self.target_group = None, []
511        self.current_selection = []
512       
513        self.resize(800, 600)
514
515    def clear(self):
516        self.target_widget.set_labels([])
517        self.targets = []
518        self.label_selections = []
519        self.target_group = None, []
520        self.clear_graph()
521       
522    def clear_graph(self):
523        self.values = {}
524        self.graph.setPlotValues({})
525        self.updateTooltips()
526       
527    def setData(self, data=None):
528        self.closeContext("")
529        self.closeContext("targets")
530        self.clear()
531        self.data = data
532        self.error(0)
533        self.warning([0,1])
534        if data:
535            self.genes_in_columns = not bool(data.domain.classVar)
536            self.genesInColumnsCheck.setDisabled(not bool(data.domain.classVar))
537            if self.genes_in_columns:
538                self.genes_in_columns = not data_hints.get_hint(data, "genesinrows", not self.genes_in_columns)
539            self.openContext("", data)
540        else:
541            self.infoLabel.setText("No data on input.")
542        self.init_from_data()
543           
544    def init_from_data(self):
545        """ Init widget state from the data.
546        """ 
547        self.update_target_labels()
548        self.error(0)
549        if self.data:
550            if not self.targets:
551                if self.genes_in_columns:
552                    self.error(0, "Data set with no column labels (attribute tags)")
553                else:
554                    self.error(0, "Data has no class.")
555       
556        self.openContext("targets", [(label, v) for label, vals in self.targets \
557                                                for v in vals])
558       
559        if len(self.label_selections) != len(self.targets): # Some times this happens.
560            self.label_selections = [[] for t in self.targets]
561           
562        if self.target_group == (None, []) and self.targets:
563            label, values = self.targets[0]
564            self.target_group = (label, values[:1])
565           
566        if self.target_group != (None, []):
567            self.target_widget.set_selection(*self.target_group)
568        else:
569            self.clear_graph()
570
571    def update_target_labels(self):
572        if self.data:
573            if self.genes_in_columns:
574                items = [a.attributes.items() for a in self.data.domain.attributes]
575                items = reduce(add, items, [])
576               
577                targets = defaultdict(set)
578                for label, value in items:
579                    targets[label].add(value)
580                   
581                targets = [(key, list(sorted(vals))) for key, vals in targets.items() \
582                           if len(vals) >= 2]
583                self.targets = targets
584               
585            else:
586                var = self.data.domain.classVar
587                values = list(var.values)
588                if len(values) >= 2:
589                    self.targets = [(var.name, values)]
590                else:
591                    self.targets = []
592        else:
593            self.targets = []
594           
595        if self.targets:
596            label, values = self.targets[0]
597            self.target_group = (label, values[:1])
598        else:
599            self.target_group = None, []
600           
601        self.label_selections = [[] for t in self.targets]
602        self.target_widget.set_labels(self.targets)
603               
604       
605    def on_label_activated(self, index):
606        """ Try to restore a saved selection.
607        """
608        selected = self.label_selections[index]
609        if not selected:
610            selected = self.targets[index][1][:1]
611           
612        self.target_widget.set_selection(index, selected)
613       
614    def on_target_changed(self, label, values):
615        self.target_group = label, values
616        # Save the selection
617        labels = [l for l, _ in self.targets]
618        if label in labels:
619            index = labels.index(label)
620            self.label_selections[index] = values
621           
622        # replot
623        if label and values:
624            self.plot()
625        else:
626            self.clear_graph()
627   
628    @disable_controls
629    def plot(self):
630        self.values = {}
631        self.current_selection = []
632        target_label, target_values = self.target_group
633        self.warning([0, 1])
634        self.error(1)
635        if self.data and target_values:
636            target_label, target_values = self.target_group
637            if self.genes_in_columns:
638                target = set([(target_label, value) for value in target_values])
639            else:
640                target = set(target_values)
641           
642            ttest = obiExpression.ExpressionSignificance_TTest(self.data, useAttributeLabels=self.genes_in_columns)
643            ind1, ind2 = ttest.test_indices(target)
644           
645            if not len(ind1) or not len(ind2):
646                self.error(1, "Target labels most exclude/include at least one value.")
647               
648            if len(ind1) < 2 and len(ind2) < 2:
649                self.warning(0, "Insufficient data to compute statistics. More than one measurement per class should be provided")
650           
651            self.progressBarInit()
652            try:
653                tt = ttest(target)
654                self.progressBarSet(25)
655                fold = obiExpression.ExpressionSignificance_FoldChange(self.data, useAttributeLabels=self.genes_in_columns)(target)
656                self.progressBarSet(50)
657            except ZeroDivisionError, ex:
658                tt, fold = [], []
659            self.infoLabel.setText("%i genes on input" % len(fold))
660           
661            invalid = set([key for (key, (t, p)), (_, f) in zip(tt, fold) if any(v is numpy.ma.masked for v in [t, p, f]) or f==0.0])
662            tt = [t for t in tt if t[0] not in invalid]
663            fold = [f for f in fold if f[0] not in invalid]
664            self.progressBarSet(75)
665            logratio = numpy.log2(numpy.abs([v for k, v in fold]))
666            logpval = -numpy.log10([p for k, (t, p) in tt])
667            self.values = dict(zip([k for k, v in tt], zip(logratio, logpval)))
668            if not self.values:
669                self.warning(1, "Could not compute statistics for any genes!")
670            self.progressBarFinished()
671        self.graph.setPlotValues(self.values)
672        self.setAxesTitles()
673        self.updateTooltips()
674
675    def setAxesTitles(self):
676        self.graph.setAxisTitle(QwtPlot.xBottom, "log<sub>2</sub> (ratio)" if self.showXTitle else "")
677        self.graph.setAxisTitle(QwtPlot.yLeft, "-log<sub>10</sub> (p_value)" if self.showYTitle else "")
678
679    def updateTooltips(self):
680        self.graph.tips.removeAll()
681        for key, (logratio, logpval) in self.values.items():
682            self.graph.tips.addToolTip(logratio, logpval, "<b>%s</b><hr>log<sub>2</sub>(ratio): %.5f<br>p-value: %.5f" \
683                                       %(str(key) if self.genes_in_columns else key.name, logratio, math.pow(10, -logpval)))
684           
685    def selection(self, items=None):
686        """ Return the current selection.
687        """
688        if items is None:
689            items = sorted(self.values.items())
690        values = [val for key, val in items]
691        test = self.graph.selection.testSelection(values)
692        return test
693   
694    def on_selection_changed(self):
695        """ Called when user changes the selection area on the plot.
696        """
697        if self.auto_commit:
698            selection = list(self.selection())
699            # Did the selection actually change
700            if selection != self.current_selection: 
701                self.current_selection = selection
702                self.commit()
703        else:
704            self.selection_changed_flag = True
705   
706    def commit(self):
707        if self.data and self.genes_in_columns:
708            items = sorted(self.values.items())
709            test = self.selection(items)
710            selected = [self.data[i] for t, (i, value) in zip(test, items) if t]
711            if selected:
712                data = orange.ExampleTable(self.data.domain, selected)
713            else:
714                data = None
715            self.current_selection = list(test) # For testing in on_selection_changed
716        elif self.data:
717            attrs = [(attr, self.values[attr])  for attr in self.data.domain.attributes if attr in self.values]
718            test = self.selection(attrs)
719#            test = self.graph.selection.testSelection([val for attr, val in attrs])
720            selected = [attr for t, (attr, val) in zip(test, attrs) if t]
721            newdomain = orange.Domain(selected + [self.data.domain.classVar])
722            newdomain.addmetas(self.data.domain.getmetas())
723            data = orange.ExampleTable(newdomain, self.data)
724            self.current_selection = list(test) # For testing in on_selection_changed
725        else:
726            data = None
727       
728        self.send("Examples with selected attributes", data)
729        self.selection_changed_flag = False
730
731    def commit_if(self):
732        if self.auto_commit:
733            self.commit()
734        else:
735            self.selection_changed_flag = True
736           
737    def settingsToWidgetCallbacktargets(self, handler, context):
738        self.label_selections = list(getattr(context, "label_selections", self.label_selections))
739        self.target_group = getattr(context, "target_group", self.target_group)
740       
741    def settingsFromWidgetCallbacktargets(self, handler, context):
742        context.label_selections = list(self.label_selections)
743        context.target_group = self.target_group
744       
745if __name__ == "__main__":
746    ap = QApplication(sys.argv)
747    w = OWVulcanoPlot()
748##    d = orange.ExampleTable("E:\\affy(HD-CC)_GS_C2cpC5.tab")
749#    d = orange.ExampleTable("E:\\steroltalk-smallchip.tab")
750    d = orange.ExampleTable("../../../doc/datasets/brown-selected.tab")
751    w.setData(d)
752    w.show()
753    ap.exec_()
754    w.saveSettings()
755
756               
757       
Note: See TracBrowser for help on using the repository browser.