source: orange-bioinformatics/Orange/bioinformatics/widgets/OWVulcanoPlot.py @ 1625:cefeb35cbfc9

Revision 1625:cefeb35cbfc9, 28.2 KB checked in by mitar, 2 years ago (diff)

Moving files around.

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