source: orange/Orange/OrangeWidgets/Visualize/OWSieveDiagram.py @ 11096:cf7d2ae9d22b

Revision 11096:cf7d2ae9d22b, 25.9 KB checked in by Ales Erjavec <ales.erjavec@…>, 19 months ago (diff)

Added new svg icons for the widgets/categories.

Line 
1"""
2<name>Sieve Diagram</name>
3<description>Sieve diagram.</description>
4<contact>Gregor Leban (gregor.leban@fri.uni-lj.si)</contact>
5<icon>icons/SieveDiagram.svg</icon>
6<priority>4200</priority>
7"""
8# OWSieveDiagram.py
9#
10from OWWidget import *
11import orngInteract, OWGUI
12from OWQCanvasFuncts import *
13from math import sqrt, floor, ceil, pow
14from orngCI import FeatureByCartesianProduct
15import random
16from OWTools import getHtmlCompatibleString
17from OWDlgs import OWChooseImageSizeDlg
18from OWMosaicOptimization import *
19
20###########################################################################################
21##### WIDGET :
22###########################################################################################
23class OWSieveDiagram(OWWidget):
24    settingsList = ["showLines", "showCases", "showInColor"]
25
26    def __init__(self,parent=None, signalManager = None):
27        OWWidget.__init__(self, parent, signalManager, "Sieve diagram", TRUE)
28
29        #self.controlArea.setMinimumWidth(250)
30
31        self.inputs = [("Data", ExampleTable, self.setData, Default), ("Features", AttributeList, self.setShownAttributes)]
32        self.outputs = []
33
34        #set default settings
35        self.data = None
36
37        self.attrX = ""
38        self.attrY = ""
39        self.attrCondition = None
40        self.attrConditionValue = None
41        self.showLines = 1
42        self.showCases = 0
43        self.showInColor = 1
44        self.attributeSelectionList = None
45        self.stopCalculating = 0
46
47        #load settings
48        self.loadSettings()
49
50        self.canvas = QGraphicsScene()
51        self.canvasView = QGraphicsView(self.canvas, self.mainArea)
52        self.mainArea.layout().addWidget(self.canvasView)
53        self.canvasView.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
54        self.canvasView.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
55
56        #GUI
57        self.attrSelGroup = OWGUI.widgetBox(self.controlArea, box = "Shown attributes")
58
59        self.attrXCombo = OWGUI.comboBoxWithCaption(self.attrSelGroup, self, "attrX", "X attribute:", tooltip = "Select an attribute to be shown on the X axis", callback = self.updateGraph, sendSelectedValue = 1, valueType = str, labelWidth = 70)
60        self.attrYCombo = OWGUI.comboBoxWithCaption(self.attrSelGroup, self, "attrY", "Y attribute:", tooltip = "Select an attribute to be shown on the Y axis", callback = self.updateGraph, sendSelectedValue = 1, valueType = str, labelWidth = 70)
61
62        OWGUI.separator(self.controlArea)
63       
64        self.conditionGroup = OWGUI.widgetBox(self.controlArea, box = "Condition")
65        self.attrConditionCombo      = OWGUI.comboBoxWithCaption(self.conditionGroup, self, "attrCondition", "Attribute:", callback = self.updateConditionAttr, sendSelectedValue = 1, valueType = str, labelWidth = 70)
66        self.attrConditionValueCombo = OWGUI.comboBoxWithCaption(self.conditionGroup, self, "attrConditionValue", "Value:", callback = self.updateGraph, sendSelectedValue = 1, valueType = str, labelWidth = 70)
67
68        OWGUI.separator(self.controlArea)
69       
70        box2 = OWGUI.widgetBox(self.controlArea, box = "Visual settings")
71        OWGUI.checkBox(box2, self, "showLines", "Show lines", callback = self.updateGraph)
72        hbox = OWGUI.widgetBox(box2, orientation = "horizontal")
73        OWGUI.checkBox(hbox, self, "showCases", "Show data examples...", callback = self.updateGraph)
74        OWGUI.checkBox(hbox, self, "showInColor", "...in color", callback = self.updateGraph)
75       
76        OWGUI.separator(self.controlArea)
77        self.optimizationDlg = OWSieveOptimization(self, self.signalManager)
78        optimizationButtons = OWGUI.widgetBox(self.controlArea, "Dialogs", orientation = "horizontal")
79        OWGUI.button(optimizationButtons, self, "VizRank", callback = self.optimizationDlg.reshow, debuggingEnabled = 0, tooltip = "Find attribute groups with highest value dependency")
80       
81        OWGUI.rubber(self.controlArea)
82       
83        self.wdChildDialogs = [self.optimizationDlg]        # used when running widget debugging
84        self.connect(self.graphButton, SIGNAL("clicked()"), self.saveToFileCanvas)
85        self.icons = self.createAttributeIconDict()
86        self.resize(800, 550)
87        random.seed()
88       
89    def sendReport(self):
90        self.startReport("%s [%s, %s]" % (self.windowTitle(), self.attrX, self.attrY))
91        self.reportSettings("",
92                            [("X-Attribute", self.attrX), ("Y-Attribute", self.attrY),
93                             self.attrCondition != "(None)" and ("Condition", "%s = '%s'" % (self.attrCondition, self.attrConditionValue))])
94        self.reportImage(lambda *x: OWChooseImageSizeDlg(self.canvas).saveImage(*x))
95
96
97    # receive new data and update all fields
98    def setData(self, data):
99        self.information(0)
100        self.information(1)
101        sameDomain = self.data and data and self.data.domain.checksum() == data.domain.checksum() # preserve attribute choice if the domain is the same
102        self.data = self.optimizationDlg.setData(data, 0)
103
104        if data:
105            if data.domain.hasContinuousAttributes():
106                self.information(0, "Continuous attributes were discretized using entropy discretization.")
107#            if not self.data or len(data.domain) != len(self.data.domain):
108#                self.information(1, "Unused attribute values were removed.")
109       
110        if not sameDomain:
111            self.initCombos()
112
113        self.setShownAttributes(self.attributeSelectionList)
114
115    ## Attribute selection signal
116    def setShownAttributes(self, attrList):
117        self.attributeSelectionList = attrList
118        if self.data and self.attributeSelectionList and len(attrList) >= 2:
119            attrs = [attr.name for attr in self.data.domain]
120            if attrList[0] in attrs and attrList[1] in attrs:
121                self.attrX = attrList[0]
122                self.attrY = attrList[1]
123        self.updateGraph()
124
125
126   
127    # create data subset depending on conditional attribute and value
128    def getConditionalData(self, xAttr = None, yAttr = None, dropMissingData = 1):
129        if not self.data: return None
130
131        if not xAttr: xAttr = self.attrX
132        if not yAttr: yAttr = self.attrY
133        if not (xAttr and yAttr): return       
134       
135        if self.attrCondition == "(None)":
136            data = self.data.select([xAttr, yAttr])
137        else:
138            data = orange.Preprocessor_dropMissing(self.data.select([xAttr, yAttr, self.attrCondition]))
139            data = data.select({self.attrCondition:self.attrConditionValue})
140
141        if dropMissingData: return orange.Preprocessor_dropMissing(data)
142        else: return data
143
144    # new conditional attribute was set - update graph
145    def updateConditionAttr(self):
146        self.attrConditionValueCombo.clear()
147       
148        if self.attrCondition != "(None)":
149            for val in self.data.domain[self.attrCondition].values:
150                self.attrConditionValueCombo.addItem(val)
151            self.attrConditionValue = str(self.attrConditionValueCombo.itemText(0))
152        self.updateGraph()
153
154    # initialize lists for shown and hidden attributes
155    def initCombos(self):
156        self.attrXCombo.clear()
157        self.attrYCombo.clear()
158        self.attrConditionCombo.clear()       
159        self.attrConditionCombo.addItem("(None)")
160        self.attrConditionValueCombo.clear()
161
162        if not self.data: return
163        for i in range(len(self.data.domain)):
164            self.attrXCombo.addItem(self.icons[self.data.domain[i].varType], self.data.domain[i].name)
165            self.attrYCombo.addItem(self.icons[self.data.domain[i].varType], self.data.domain[i].name)
166            self.attrConditionCombo.addItem(self.icons[self.data.domain[i].varType], self.data.domain[i].name)
167        self.attrCondition = str(self.attrConditionCombo.itemText(0))
168
169        if self.attrXCombo.count() > 0:
170            self.attrX = str(self.attrXCombo.itemText(0))
171            self.attrY = str(self.attrYCombo.itemText(self.attrYCombo.count() > 1))
172
173    def resizeEvent(self, e):
174        OWWidget.resizeEvent(self,e)
175        self.updateGraph()
176
177    def showEvent(self, ev):
178        OWWidget.showEvent(self, ev)
179        self.updateGraph()
180
181    ## updateGraph - gets called every time the graph has to be updated
182    def updateGraph(self, *args):
183        for item in self.canvas.items():
184            self.canvas.removeItem(item)    # remove all canvas items
185        if not self.data: return
186        if not self.attrX or not self.attrY: return
187
188        data = self.getConditionalData()
189        if not data or len(data) == 0: return
190
191        valsX = []
192        valsY = []
193        contX = orange.ContingencyAttrAttr(self.attrX, self.attrX, data)   # distribution of X attribute
194        contY = orange.ContingencyAttrAttr(self.attrY, self.attrY, data)   # distribution of Y attribute
195
196        # compute contingency of x and y attributes
197        for key in contX.keys():
198            sum = 0
199            try:
200                for val in contX[key]: sum += val
201            except: pass
202            valsX.append(sum)
203
204        for key in contY.keys():
205            sum = 0
206            try:
207                for val in contY[key]: sum += val
208            except: pass
209            valsY.append(sum)
210
211        # create cartesian product of selected attributes and compute contingency
212        (cart, profit) = FeatureByCartesianProduct(data, [data.domain[self.attrX], data.domain[self.attrY]])
213        tempData = data.select(list(data.domain) + [cart])
214        contXY = orange.ContingencyAttrAttr(cart, cart, tempData)   # distribution of X attribute
215
216        # compute probabilities
217        probs = {}
218        for i in range(len(valsX)):
219            valx = valsX[i]
220            for j in range(len(valsY)):
221                valy = valsY[j]
222
223                actualProb = 0
224                try:
225                    for val in contXY['%s-%s' %(contX.keys()[i], contY.keys()[j])]: actualProb += val
226                except:
227                    actualProb = 0
228                probs['%s-%s' %(contX.keys()[i], contY.keys()[j])] = ((contX.keys()[i], valx), (contY.keys()[j], valy), actualProb, len(data))
229
230        # get text width of Y attribute name
231        text = OWCanvasText(self.canvas, data.domain[self.attrY].name, x  = 0, y = 0, bold = 1, show = 0)
232        xOff = int(text.boundingRect().width() + 40)
233        yOff = 50
234        sqareSize = min(self.canvasView.width() - xOff - 35, self.canvasView.height() - yOff - 30)
235        if sqareSize < 0: return    # canvas is too small to draw rectangles
236        self.canvasView.setSceneRect(0, 0, self.canvasView.width(), self.canvasView.height())
237
238        # print graph name
239        if self.attrCondition == "(None)":
240            name  = "<b>P(%s, %s) &#8800; P(%s)&times;P(%s)</b>" %(self.attrX, self.attrY, self.attrX, self.attrY)
241        else:
242            name = "<b>P(%s, %s | %s = %s) &#8800; P(%s | %s = %s)&times;P(%s | %s = %s)</b>" %(self.attrX, self.attrY, self.attrCondition, getHtmlCompatibleString(self.attrConditionValue), self.attrX, self.attrCondition, getHtmlCompatibleString(self.attrConditionValue), self.attrY, self.attrCondition, getHtmlCompatibleString(self.attrConditionValue))
243        OWCanvasText(self.canvas, "" , xOff+ sqareSize/2, 20, Qt.AlignCenter, htmlText = name)
244        OWCanvasText(self.canvas, "N = " + str(len(data)), xOff+ sqareSize/2, 38, Qt.AlignCenter, bold = 0)
245
246        ######################
247        # compute chi-square
248        chisquare = 0.0
249        for i in range(len(valsX)):
250            for j in range(len(valsY)):
251                ((xAttr, xVal), (yAttr, yVal), actual, sum) = probs['%s-%s' %(contX.keys()[i], contY.keys()[j])]
252                expected = float(xVal*yVal)/float(sum)
253                if expected == 0: continue
254                pearson2 = (actual - expected)*(actual - expected) / expected
255                chisquare += pearson2
256
257        ######################
258        # draw rectangles
259        currX = xOff
260        for i in range(len(valsX)):
261            if valsX[i] == 0: continue
262            currY = yOff
263            width = int(float(sqareSize * valsX[i])/float(len(data)))
264
265            #for j in range(len(valsY)):
266            for j in range(len(valsY)-1, -1, -1):   # this way we sort y values correctly
267                ((xAttr, xVal), (yAttr, yVal), actual, sum) = probs['%s-%s' %(contX.keys()[i], contY.keys()[j])]
268                if valsY[j] == 0: continue
269                height = int(float(sqareSize * valsY[j])/float(len(data)))
270
271                # create rectangle
272                rect = OWCanvasRectangle(self.canvas, currX+2, currY+2, width-4, height-4, z = -10)
273                self.addRectIndependencePearson(rect, currX+2, currY+2, width-4, height-4, (xAttr, xVal), (yAttr, yVal), actual, sum)
274
275                expected = float(xVal*yVal)/float(sum)
276                pearson = (actual - expected) / sqrt(expected)
277                tooltipText = """<b>X Attribute: %s</b><br>Value: <b>%s</b><br>Number of examples (p(x)): <b>%d (%.2f%%)</b><hr>
278                                <b>Y Attribute: %s</b><br>Value: <b>%s</b><br>Number of examples (p(y)): <b>%d (%.2f%%)</b><hr>
279                                <b>Number Of Examples (Probabilities):</b><br>Expected (p(x)p(y)): <b>%.1f (%.2f%%)</b><br>Actual (p(x,y)): <b>%d (%.2f%%)</b>
280                                <hr><b>Statistics:</b><br>Chi-square: <b>%.2f</b><br>Standardized Pearson residual: <b>%.2f</b>""" %(self.attrX, getHtmlCompatibleString(xAttr), xVal, 100.0*float(xVal)/float(sum), self.attrY, getHtmlCompatibleString(yAttr), yVal, 100.0*float(yVal)/float(sum), expected, 100.0*float(xVal*yVal)/float(sum*sum), actual, 100.0*float(actual)/float(sum), chisquare, pearson )
281                rect.setToolTip(tooltipText)
282
283                currY += height
284                if currX == xOff:
285                    OWCanvasText(self.canvas, "", xOff - 10, currY - height/2, Qt.AlignRight | Qt.AlignVCenter, htmlText = getHtmlCompatibleString(data.domain[self.attrY].values[j]))
286
287            OWCanvasText(self.canvas, "", currX + width/2, yOff + sqareSize + 5, Qt.AlignCenter, htmlText = getHtmlCompatibleString(data.domain[self.attrX].values[i]))
288            currX += width
289
290        # show attribute names
291        OWCanvasText(self.canvas, self.attrY, xOff-20, yOff + sqareSize/2, Qt.AlignRight, bold = 1)
292        OWCanvasText(self.canvas, self.attrX, xOff + sqareSize/2, yOff + sqareSize + 15, Qt.AlignCenter, bold = 1)
293
294        #self.canvas.update()
295
296    ######################################################################
297    ## show deviations from attribute independence with standardized pearson residuals
298    def addRectIndependencePearson(self, rect, x, y, w, h, (xAttr, xVal), (yAttr, yVal), actual, sum):
299        expected = float(xVal*yVal)/float(sum)
300        pearson = (actual - expected) / sqrt(expected)
301
302        if pearson > 0:     # if there are more examples that we would expect under the null hypothesis
303            intPearson = floor(pearson)
304            pen = QPen(QColor(0,0,255), 1); rect.setPen(pen)
305            b = 255
306            r = g = 255 - intPearson*20
307            r = g = max(r, 55)  #
308        elif pearson < 0:
309            intPearson = ceil(pearson)
310            pen = QPen(QColor(255,0,0), 1)
311            rect.setPen(pen)
312            r = 255
313            b = g = 255 + intPearson*20
314            b = g = max(b, 55)
315        else:
316            pen = QPen(QColor(255,255,255), 1)
317            r = g = b = 255         # white
318        color = QColor(r,g,b)
319        brush = QBrush(color); rect.setBrush(brush)
320
321        if self.showCases and w > 6 and h > 6:
322            if self.showInColor:
323                if pearson > 0: c = QColor(0,0,255)
324                else: c = QColor(255, 0,0)
325            else: c = Qt.black
326            for i in range(int(actual)):
327                OWCanvasEllipse(self.canvas, random.randint(x+1, x + w-4), random.randint(y+1, y + h-4), 3, 3, penColor = c, brushColor = c, z = 100)
328
329        if pearson > 0:
330            pearson = min(pearson, 10)
331            kvoc = 1 - 0.08 * pearson       #  if pearson in [0..10] --> kvoc in [1..0.2]
332        else:
333            pearson = max(pearson, -10)
334            kvoc = 1 - 0.4*pearson
335       
336        self.addLines(x,y,w,h, kvoc, pen)
337
338
339    ##################################################
340    # add lines
341    def addLines(self, x,y,w,h, diff, pen):
342        if not self.showLines: return
343        if w == 0 or h == 0: return
344
345        # create lines
346        dist = 20   # original distance between two lines in pixels
347        dist = dist * diff
348        temp = dist
349        while (temp < w):
350            OWCanvasLine(self.canvas, temp+x, y, temp+x, y+h, 1, pen.color())
351            temp += dist
352
353        temp = dist
354        while (temp < h):
355            OWCanvasLine(self.canvas, x, y+temp, x+w, y+temp, 1, pen.color())
356            temp += dist
357
358    def saveToFileCanvas(self):
359        sizeDlg = OWChooseImageSizeDlg(self.canvas, parent=self)
360        sizeDlg.exec_()
361
362    def closeEvent(self, ce):
363        self.optimizationDlg.hide()
364        QDialog.closeEvent(self, ce)
365
366class OWSieveOptimization(OWMosaicOptimization, orngMosaic):
367    settingsList = ["percentDataUsed", "ignoreTooSmallCells",
368                    "timeLimit", "useTimeLimit", "lastSaveDirName", "projectionLimit", "useProjectionLimit"]
369
370    def __init__(self, visualizationWidget = None, signalManager = None):
371        OWWidget.__init__(self, None, signalManager, "Sieve Evaluation Dialog", savePosition = True, wantMainArea = 0, wantStatusBar = 1)
372        orngMosaic.__init__(self)
373
374        self.resize(390,620)
375        self.setCaption("Sieve Diagram Evaluation Dialog")
376       
377        # loaded variables
378        self.visualizationWidget = visualizationWidget
379        self.useTimeLimit = 0
380        self.useProjectionLimit = 0
381        self.qualityMeasure = CHI_SQUARE        # we will always compute only chi square with sieve diagram
382        self.optimizationType = EXACT_NUMBER_OF_ATTRS
383        self.attributeCount = 2
384        self.attrCondition = None
385        self.attrConditionValue = None
386
387        self.lastSaveDirName = os.getcwd()
388
389        self.attrLenDict = {}
390        self.shownResults = []
391        self.loadSettings()
392       
393        self.layout().setMargin(0)
394        self.tabs = OWGUI.tabWidget(self.controlArea)
395        self.MainTab = OWGUI.createTabPage(self.tabs, "Main")
396        self.SettingsTab = OWGUI.createTabPage(self.tabs, "Settings")
397        self.ManageTab = OWGUI.createTabPage(self.tabs, "Manage")
398
399        # ###########################
400        # MAIN TAB
401        box = OWGUI.widgetBox(self.MainTab, box = "Condition")
402        self.attrConditionCombo      = OWGUI.comboBoxWithCaption(box, self, "attrCondition", "Attribute:", callback = self.updateConditionAttr, sendSelectedValue = 1, valueType = str, labelWidth = 70)
403        self.attrConditionValueCombo = OWGUI.comboBoxWithCaption(box, self, "attrConditionValue", "Value:", sendSelectedValue = 1, valueType = str, labelWidth = 70)
404
405        self.optimizationBox = OWGUI.widgetBox(self.MainTab, "Evaluate")
406        self.buttonBox = OWGUI.widgetBox(self.optimizationBox, orientation = "horizontal")
407        self.resultsBox = OWGUI.widgetBox(self.MainTab, "Projection List Ordered by Chi-Square")
408
409#        self.label1 = OWGUI.widgetLabel(self.buttonBox, 'Projections with ')
410#        self.optimizationTypeCombo = OWGUI.comboBox(self.buttonBox, self, "optimizationType", items = ["    exactly    ", "  maximum  "] )
411#        self.attributeCountCombo = OWGUI.comboBox(self.buttonBox, self, "attributeCount", items = range(1, 5), tooltip = "Evaluate only projections with exactly (or maximum) this number of attributes", sendSelectedValue = 1, valueType = int)
412#        self.attributeLabel = OWGUI.widgetLabel(self.buttonBox, ' attributes')
413
414        self.startOptimizationButton = OWGUI.button(self.optimizationBox, self, "Start Evaluating Projections", callback = self.evaluateProjections)
415        f = self.startOptimizationButton.font(); f.setBold(1);   self.startOptimizationButton.setFont(f)
416        self.stopOptimizationButton = OWGUI.button(self.optimizationBox, self, "Stop Evaluation", callback = self.stopEvaluationClick)
417        self.stopOptimizationButton.setFont(f)
418        self.stopOptimizationButton.hide()
419
420        self.resultList = OWGUI.listBox(self.resultsBox, self, callback = self.showSelectedAttributes)
421        self.resultList.setMinimumHeight(200)
422
423        # ##########################
424        # SETTINGS TAB
425        OWGUI.checkBox(self.SettingsTab, self, "ignoreTooSmallCells", "Ignore cells where expected number of cases is less than 5", box = "Ignore small cells", tooltip = "Statisticians advise that in cases when the number of expected examples is less than 5 we ignore the cell \nsince it can significantly influence the chi-square value.")
426       
427        OWGUI.comboBoxWithCaption(self.SettingsTab, self, "percentDataUsed", "Percent of data used: ", box = "Data settings", items = self.percentDataNums, sendSelectedValue = 1, valueType = int, tooltip = "In case that we have a large dataset the evaluation of each projection can take a lot of time.\nWe can therefore use only a subset of randomly selected examples, evaluate projection on them and thus make evaluation faster.")
428
429        self.stopOptimizationBox = OWGUI.widgetBox(self.SettingsTab, "When to Stop Evaluation or Optimization?")
430        OWGUI.checkWithSpin(self.stopOptimizationBox, self, "Time limit:                     ", 1, 1000, "useTimeLimit", "timeLimit", "  (minutes)", debuggingEnabled = 0)      # disable debugging. we always set this to 1 minute
431        OWGUI.checkWithSpin(self.stopOptimizationBox, self, "Use projection count limit:  ", 1, 1000000, "useProjectionLimit", "projectionLimit", "  (projections)", debuggingEnabled = 0)
432        OWGUI.rubber(self.SettingsTab)
433
434        # ##########################
435        # SAVE TAB
436#        self.visualizedAttributesBox = OWGUI.widgetBox(self.ManageTab, "Number of Concurrently Visualized Attributes")
437        self.dialogsBox = OWGUI.widgetBox(self.ManageTab, "Dialogs")
438        self.manageResultsBox = OWGUI.widgetBox(self.ManageTab, "Manage projections")
439
440#        self.attrLenList = OWGUI.listBox(self.visualizedAttributesBox, self, selectionMode = QListWidget.MultiSelection, callback = self.attrLenListChanged)
441#        self.attrLenList.setMinimumHeight(60)
442
443        self.buttonBox7 = OWGUI.widgetBox(self.dialogsBox, orientation = "horizontal")
444        OWGUI.button(self.buttonBox7, self, "Attribute Ranking", self.attributeAnalysis, debuggingEnabled = 0)
445        OWGUI.button(self.buttonBox7, self, "Graph Projection Scores", self.graphProjectionQuality, debuggingEnabled = 0)
446
447        hbox = OWGUI.widgetBox(self.manageResultsBox, orientation = "horizontal")
448        OWGUI.button(hbox, self, "Load", self.load, debuggingEnabled = 0)
449        OWGUI.button(hbox, self, "Save", self.save, debuggingEnabled = 0)
450
451        hbox = OWGUI.widgetBox(self.manageResultsBox, orientation = "horizontal")
452        OWGUI.button(hbox, self, "Clear results", self.clearResults)
453        OWGUI.rubber(self.ManageTab)
454
455        # reset some parameters if we are debugging so that it won't take too much time
456        if orngDebugging.orngDebuggingEnabled:
457            self.useTimeLimit = 1
458            self.timeLimit = 0.3
459            self.useProjectionLimit = 1
460            self.projectionLimit = 100
461        self.icons = self.createAttributeIconDict()
462
463   
464    # when we start evaluating projections save info on the condition - this has to be stored in the
465    def evaluateProjections(self):
466        if not self.data: return
467        self.usedAttrCondition = self.attrCondition
468        self.usedAttrConditionValue = self.attrConditionValue
469        self.wholeDataSet = self.data           # we have to create a datasubset based on the attrCondition
470        if self.attrCondition != "(None)":
471            self.data = self.data.select({self.attrCondition : self.attrConditionValue})
472        orngMosaic.setData(self, self.data)
473        OWMosaicOptimization.evaluateProjections(self)
474       
475    # this is a handler that is called after we finish evaluating projections (when evaluated all projections, or stop was pressed)
476    def finishEvaluation(self, evaluatedProjections):
477        self.data = self.wholeDataSet           # restore the whole data after projection evaluation
478        OWMosaicOptimization.finishEvaluation(self, evaluatedProjections)
479       
480               
481    def showSelectedAttributes(self, attrs = None):
482        if not self.visualizationWidget: return
483        if not attrs:
484            projection = self.getSelectedProjection()
485            if not projection: return
486            self.visualizationWidget.attrCondition = self.usedAttrCondition
487            self.visualizationWidget.updateConditionAttr()
488            self.visualizationWidget.attrConditionValue = self.usedAttrConditionValue
489            (score, attrs, index, extraInfo) = projection
490
491        self.resultList.setFocus()
492        self.visualizationWidget.setShownAttributes(attrs)
493       
494
495    def clearResults(self):
496        orngMosaic.clearResults(self)
497        self.resultList.clear()
498
499    def setData(self, data, removeUnusedValues = 0):
500        self.attrConditionCombo.clear()       
501        self.attrConditionCombo.addItem("(None)")
502        self.attrConditionValueCombo.clear()
503        self.resultList.clear()
504       
505        orngMosaic.setData(self, data, removeUnusedValues)
506
507        self.setStatusBarText("")
508        if not self.data: return None
509       
510        for i in range(len(self.data.domain)):
511            self.attrConditionCombo.addItem(self.icons[self.data.domain[i].varType], self.data.domain[i].name)
512        self.attrCondition = str(self.attrConditionCombo.itemText(0))
513
514        return self.data
515
516    def finishedAddingResults(self):
517        self.resultList.setCurrentItem(self.resultList.item(0))
518   
519    def updateConditionAttr(self):
520        self.attrConditionValueCombo.clear()
521       
522        if self.attrCondition != "(None)":
523            for val in self.data.domain[self.attrCondition].values:
524                self.attrConditionValueCombo.addItem(val)
525            self.attrConditionValue = str(self.attrConditionValueCombo.itemText(0))
526   
527
528#test widget appearance
529if __name__=="__main__":
530    a=QApplication(sys.argv)
531    ow=OWSieveDiagram()
532    ow.show()
533    data = orange.ExampleTable(r"e:\Development\Orange Datasets\UCI\zoo.tab")
534    ow.setData(data)
535    a.exec_()
536    ow.saveSettings()
Note: See TracBrowser for help on using the repository browser.