source: orange/Orange/OrangeWidgets/Visualize Qt/OWDistributionsQt.py @ 9671:a7b056375472

Revision 9671:a7b056375472, 31.7 KB checked in by anze <anze.staric@…>, 2 years ago (diff)

Moved orange to Orange (part 2)

Line 
1"""
2<name>Distributions (Qt)</name>
3<description>Displays attribute value distributions.</description>
4<contact>Tomaz Curk</contact>
5<icon>icons/Distribution.png</icon>
6<priority>110</priority>
7"""
8
9#
10# OWDistributions.py
11# Shows data distributions, distribution of attribute values and distribution of classes for each attribute
12#
13
14from OWColorPalette import ColorPixmap, ColorPaletteGenerator
15from OWWidget import *
16from plot.owplot import *
17import OWGUI
18import math
19import statc
20
21from plot.owcurve import *
22from plot.owtools import *
23
24class distribErrorBarCurve(OWCurve):
25    DistributionCurve = OWCurve.UserCurve + 15
26    def __init__(self, text = None):
27        OWCurve.__init__(self)
28        self._item = QGraphicsPathItem(self)
29        self.set_style(OWCurve.Lines)
30        self.set_point_size(7)
31       
32    def update_properties(self):
33        OWCurve.update_properties(self)
34   
35        if self.style() == self.DistributionCurve:
36            d = self.data()
37            n = len(d)/3
38            p = QPainterPath()
39            for i in range(n):
40                px, py1 = d[3*i]
41                _, py2 = d[3*i+1]
42                _, py3 = d[3*i+2]
43                pxl = px - 0.1
44                pxr = px + 0.1
45                p.moveTo(px, py1)
46                p.lineTo(px, py3)
47                p.moveTo(pxl, py1)
48                p.lineTo(pxr, py1)
49                p.moveTo(pxl, py3)
50                p.lineTo(pxr, py3)
51            self._item.setPath(self.graph_transform().map(p))
52            self._item.setPen(self.pen())
53            self._item.show()
54        else:
55            self._item.hide()
56        self.set_updated(OWCurve.UpdateAll)
57
58
59class OWDistributionGraphQt(OWPlot):
60    def __init__(self, settingsWidget = None, parent = None, name = None):
61        OWPlot.__init__(self, parent, name, axes = [xBottom, yLeft, yRight])
62        self.parent = parent
63
64        # initialize settings
65        self.attributeName = ""
66        self.variableContinuous = FALSE
67        self.YLaxisTitle = "Frequency"
68
69        self.numberOfBars = 5
70        self.barSize = 50
71        self.showContinuousClassGraph=1
72        self.showProbabilities = 0
73        self.showConfidenceIntervals = 0
74        self.smoothLines = 0
75        self.hdata = {}
76        self.probGraphValues = []
77
78        self.targetValue = None
79        self.data = None
80        self.visibleOutcomes = None
81
82        self.settingsWidget = settingsWidget
83
84        self.probCurveKey = self.addCurve(xBottom, yRight, 0)
85        self.probCurveUpperCIKey = self.addCurve(xBottom, yRight, 0)
86        self.probCurveLowerCIKey = self.addCurve(xBottom, yRight, 0)
87       
88        self.axes[xBottom].arrows = 0
89
90    def addCurve(self, xAxis = xBottom, yAxis = yLeft, visible = 1):
91        curve = distribErrorBarCurve('')
92        curve.setVisible(visible)
93        curve.set_axes(xAxis, yAxis)
94        curve.set_color(self.color(OWPalette.Data))
95        return OWPlot.add_custom_curve(self, curve, enableLegend=0)
96
97    def sizeHint(self):
98        return QSize(500, 500)
99
100    def setVisibleOutcomes(self, outcomes):
101        self.visibleOutcomes = outcomes
102
103    def setTargetValue(self, target):
104        self.targetValue = target
105        self.refreshProbGraph()
106
107    def setData(self, data, variable):
108        self.data = data
109        self.pureHistogram = not data or not data.domain.classVar or data.domain.classVar.varType!=orange.VarTypes.Discrete
110        self.dataHasClass = data and data.domain.classVar
111        self.dataHasDiscreteClass = self.dataHasClass and data.domain.classVar.varType == orange.VarTypes.Discrete
112        if self.dataHasDiscreteClass:
113            self.dc = orange.DomainContingency(self.data)
114        self.setVariable(variable)
115
116    def setVariable(self, variable):
117        self.attributeName = variable
118        if variable: self.setXaxisTitle(variable)
119        else:        self.setXaxisTitle("")
120
121        if not self.data: return
122       
123        if variable and self.data.domain[variable].varType == orange.VarTypes.Discrete and len(self.data.domain[variable].values) > 100:
124            if QMessageBox.question(self, "Confirmation", "The attribute %s has %d values. Are you sure you want to visualize this attribute?" % (variable, len(self.data.domain[variable].values)), QMessageBox.Yes , QMessageBox.No | QMessageBox.Escape | QMessageBox.Default) == QMessageBox.No:
125                self.clear()
126                self.tips.removeAll()
127                self.hdata = {}
128                return
129
130        if self.data.domain[self.attributeName].varType == orange.VarTypes.Continuous:
131            self.variableContinuous = TRUE
132        else:
133            self.variableContinuous = FALSE
134
135        if self.variableContinuous:
136            self.set_axis_labels(xBottom, None)
137        else:
138            labels = self.data.domain[self.attributeName].values.native()
139            self.set_axis_labels(xBottom, labels)
140           
141        self.calcHistogramAndProbGraph()
142        self.refreshVisibleOutcomes()
143        self.reset_zoom()
144
145    def setNumberOfBars(self, n):
146        self.numberOfBars = n
147
148        if self.variableContinuous:
149            self.calcHistogramAndProbGraph()
150            self.refreshVisibleOutcomes()
151            #self.replot()
152
153    def setBarSize(self, n):
154        self.barSize = n
155        if not(self.variableContinuous):
156            self.refreshVisibleOutcomes()
157            self.replot()
158
159    def calcPureHistogram(self):
160        if self.data==None:
161            return
162        if self.variableContinuous:
163            "Continuous variable, break data into self.NumberOfBars subintervals"
164            "use orange.EquiDistDiscretization(numberOfIntervals)"
165            equiDist = orange.EquiDistDiscretization(numberOfIntervals = self.numberOfBars)
166            d_variable = equiDist(self.attributeName, self.data)
167            d_data = self.data.select([d_variable])
168            tmphdata = orange.Distribution(0, d_data)
169
170            curPos = d_variable.getValueFrom.transformer.firstVal - d_variable.getValueFrom.transformer.step
171            self.subIntervalStep = d_variable.getValueFrom.transformer.step
172            self.hdata = {}
173            for key in tmphdata.keys():
174                self.hdata[curPos] = tmphdata[key]
175                curPos += self.subIntervalStep
176        else:
177            "Discrete variable"
178            self.hdata = orange.Distribution(self.attributeName, self.data) #self.dc[self.attributeName]
179
180    def calcHistogramAndProbGraph(self):
181        "Calculates the histogram."
182        if self.data == None:
183            return
184        if self.pureHistogram:
185            self.calcPureHistogram()
186            return
187        if self.variableContinuous:
188            "Continuous variable, break data into self.NumberOfBars subintervals"
189            "use orange.EquiDistDiscretization(numberOfIntervals)"
190            equiDist = orange.EquiDistDiscretization(numberOfIntervals = self.numberOfBars)
191            d_variable = equiDist(self.attributeName, self.data)
192#            d_data = self.data.select([d_variable, self.data.domain.classVar])
193#            tmphdata = orange.DomainContingency(d_data)[0]
194#            dc = orange.DomainContingency(self.data) #!!!
195            tmphdata = orange.ContingencyAttrClass(d_variable, self.data)
196            try:
197                g = orange.ConditionalProbabilityEstimatorConstructor_loess(self.dc[self.attributeName], nPoints=200) #!!!
198                self.probGraphValues = [(x, ps, [(v>=0 and math.sqrt(v)*1.96 or 0.0) for v in ps.variances]) for (x, ps) in g.probabilities.items()]
199            except:
200                self.probGraphValues = []
201            # print [ps.variances for (x, ps) in g.probabilities.items()]
202            # calculate the weighted CI=math.sqrt(prob*(1-prob)/(0.0+self.sums[curcol])),
203            # where self.sums[curcol] = g.probabilities.items()[example][1].cases
204
205            # change the attribute value (which is discretized) into the subinterval start value
206            # keep the same DomainContingency data
207            curPos = d_variable.getValueFrom.transformer.firstVal - d_variable.getValueFrom.transformer.step
208            self.subIntervalStep = d_variable.getValueFrom.transformer.step
209            self.hdata = {}
210            for key in tmphdata.keys():
211                self.hdata[curPos] = tmphdata[key]
212                curPos += self.subIntervalStep
213        else:
214            "Discrete variable"
215            self.hdata = self.dc[self.attributeName]
216            self.probGraphValues = []
217            for (x, ds) in self.hdata.items():
218                ps = []
219                cis = []
220                cases = ds.cases
221                for d in ds:
222                    if cases > 0:
223                        p = d / cases
224                        ci = math.sqrt(p * (1-p) / (0.0 + cases))
225                    else:
226                        p = 0
227                        ci = 0
228                    ps.append(p)
229                    cis.append(ci)
230                self.probGraphValues.append((x, ps, cis))
231
232    def refreshPureVisibleOutcomes(self):
233        if self.dataHasDiscreteClass:
234            return
235        keys=self.hdata.keys()
236        if self.variableContinuous:
237            keys.sort()
238        self.clear()
239        self.tips.removeAll()
240        cn=0
241        for key in keys:
242            ckey = PolygonCurve(pen=self.color(OWPalette.Data), brush=QBrush(self.color(OWPalette.Grid)))
243            ckey.attach(self)
244            if self.variableContinuous:
245                ckey.setData([key, key + self.subIntervalStep, key + self.subIntervalStep, key],[0, 0, self.hdata[key], self.hdata[key]])
246                ff="%."+str(self.data.domain[self.attributeName].numberOfDecimals+1)+"f"
247                text = "N(%s in ("+ff+","+ff+"])=<b>%i</b>"
248                text = text % (Qt.escape(str(self.attributeName)), key, key+self.subIntervalStep, self.hdata[key])
249                self.tips.addToolTip(key+self.subIntervalStep/2.0, self.hdata[key]/2.0, text, self.subIntervalStep/2.0, self.hdata[key]/2.0)
250            else:
251                tmpx = cn - (self.barSize/2.0)/100.0
252                tmpx2 = cn + (self.barSize/2.0)/100.0
253                ckey.setData([tmpx, tmpx2, tmpx2, tmpx], [0, 0, self.hdata[key], self.hdata[key]])
254                text = "N(%s=%s)=<b>%i</b>"%(Qt.escape(str(self.attributeName)), Qt.escape(str(key)), self.hdata[key])
255                self.tips.addToolTip(cn, self.hdata[key]/2.0, text, (self.barSize/2.0)/100.0, self.hdata[key]/2.0)
256                cn+=1
257
258        if self.dataHasClass and not self.dataHasDiscreteClass and self.showContinuousClassGraph:
259            self.enableYRaxis(1)
260#            self.setAxisAutoScale(yRight)
261            self.setYRaxisTitle(str(self.data.domain.classVar.name))
262            if self.variableContinuous:
263                equiDist = orange.EquiDistDiscretization(numberOfIntervals = self.numberOfBars)
264                d_variable = equiDist(self.attributeName, self.data)
265                d_data=self.data.select([d_variable, self.data.domain.classVar])
266                c=orange.ContingencyAttrClass(d_variable, d_data)
267                XY=[(key+self.subIntervalStep/2.0, val.average()) for key, val in zip(keys, c.values()) if val.cases]
268                XY=statc.loess(XY, 10, 4.0, 1)
269            else:
270                d_data=orange.ContingencyAttrClass(self.attributeName, self.data)
271                XY=[(i, dist.average()) for i, dist in zip(range(len(d_data.values())), d_data.values()) if dist.cases]
272            key = self.addCurve(xBottom, yRight)
273            key.setData([a[0] for a in XY], [a[1] for a in XY])
274            key.set_color(self.color(OWPalette.Data))
275            if not self.variableContinuous:
276                key.set_symbol(OWPoint.Diamond)
277                key.set_point_size(7)
278        else:
279            self.enableYRaxis(0)
280            self.setAxisScale(yRight, -0.05, 1.05, 0.1)
281
282        self.probCurveKey = self.addCurve(xBottom, yRight)
283        self.probCurveUpperCIKey = self.addCurve(xBottom, yRight)
284        self.probCurveLowerCIKey = self.addCurve(xBottom, yRight)
285
286        self.replot()
287
288    def refreshVisibleOutcomes(self):
289        if not self.data or (not self.visibleOutcomes and not self.pureHistogram): return
290        self.tips.removeAll()
291        if self.pureHistogram:
292            self.refreshPureVisibleOutcomes()
293            return
294        self.enableYRaxis(0)
295        self.setAxisScale(yRight, -0.05, 1.05, 0.1)
296        self.setYRaxisTitle("")
297        keys = self.hdata.keys()
298        if self.variableContinuous:
299            keys.sort()
300
301        self.clear()
302
303        currentBarsHeight = [0] * len(keys)
304        for oi in range(len(self.visibleOutcomes)):
305            if self.visibleOutcomes[oi] == 1:
306                #for all bars insert curve and
307                for cn, key in enumerate(keys):
308                    subBarHeight = self.hdata[key][oi]
309                    if not subBarHeight:
310                        continue
311                    ckey = PolygonCurve(pen = QPen(self.discPalette[oi]), brush = QBrush(self.discPalette[oi]))
312                    ckey.attach(self)
313                    if self.variableContinuous:
314                        ckey.setData([key, key + self.subIntervalStep, key + self.subIntervalStep, key], [currentBarsHeight[cn], currentBarsHeight[cn], currentBarsHeight[cn] + subBarHeight, currentBarsHeight[cn] + subBarHeight])
315                        ff = "%."+str(self.data.domain[self.attributeName].numberOfDecimals+1)+"f"
316                        text = "N(%s=%s|%s in ("+ff+","+ff+"])=<b>%i</b><br>P(%s=%s|%s in ("+ff+","+ff+"])=<b>%.3f</b><br>"
317                        text = text % (
318                                    Qt.escape(str(self.data.domain.classVar.name)),         
319                                    Qt.escape(str(self.data.domain.classVar[oi])), 
320                                    Qt.escape(str(self.attributeName)), 
321                                    key, key+self.subIntervalStep, subBarHeight,
322                                    Qt.escape(str(self.data.domain.classVar.name)), 
323                                    Qt.escape(str(self.data.domain.classVar[oi])), 
324                                    Qt.escape(str(self.attributeName)), 
325                                    key, key+self.subIntervalStep, float(subBarHeight/sum(self.hdata[key]))
326                                    ) 
327                                    #self.probGraphValues[cn][1][oi])
328                        self.tips.addToolTip(key+self.subIntervalStep/2.0, currentBarsHeight[cn] + subBarHeight/2.0, text, self.subIntervalStep/2.0, subBarHeight/2.0)
329                    else:
330                        tmpx = cn - (self.barSize/2.0)/100.0
331                        tmpx2 = cn + (self.barSize/2.0)/100.0
332                        ckey.setData([tmpx, tmpx2, tmpx2, tmpx], [currentBarsHeight[cn], currentBarsHeight[cn], currentBarsHeight[cn] + subBarHeight, currentBarsHeight[cn] + subBarHeight])
333                        text = "N(%s=%s|%s=%s)=<b>%i</b><br>P(%s=%s|%s=%s)=<b>%.3f</b>"
334                        text = text % (
335                                    Qt.escape(str(self.data.domain.classVar.name)), 
336                                    Qt.escape(str(self.data.domain.classVar[oi])), 
337                                    Qt.escape(str(self.attributeName)), 
338                                    Qt.escape(str(key)), subBarHeight,
339                                    Qt.escape(str(self.data.domain.classVar.name)), 
340                                    Qt.escape(str(self.data.domain.classVar[oi])), 
341                                    Qt.escape(str(self.attributeName)), 
342                                    Qt.escape(str(key)), float(subBarHeight/sum(self.hdata[key])))
343                        self.tips.addToolTip(cn, currentBarsHeight[cn]+subBarHeight/2.0, text, (self.barSize/2.0)/100.0, subBarHeight/2.0)
344                    currentBarsHeight[cn] += subBarHeight
345
346        self.probCurveKey = self.addCurve(xBottom, yRight)
347        self.probCurveUpperCIKey = self.addCurve(xBottom, yRight)
348        self.probCurveLowerCIKey = self.addCurve(xBottom, yRight)
349        self.refreshProbGraph()
350
351    def refreshProbGraph(self):
352        if not self.data or self.targetValue == None: return
353        if self.showProbabilities:
354            self.enableYRaxis(1)
355            if self.variableContinuous:
356                self.set_axis_scale(xBottom, self.probGraphValues[0][0], self.probGraphValues[-1][0])
357          #  self.setShowYRaxisTitle(self.showYRaxisTitle)
358          #  self.setYRaxisTitle(self.YRaxisTitle)
359            xs = []
360            ups = []
361            mps = []
362            lps = []
363            cn = 0.0
364            for (x, ps, cis) in self.probGraphValues:
365                if self.variableContinuous:
366                    xs.append(x)
367                    ups.append(ps[self.targetValue] + cis[self.targetValue])
368                    mps.append(ps[self.targetValue] + 0.0)
369                    lps.append(ps[self.targetValue] - cis[self.targetValue])
370                else:
371                    ## We make 3x as many points in both cases.
372                    ## This way animations look better when switching the ConfidenceIntervals on and off
373                    xs.extend([cn] * 3)
374                    if self.showConfidenceIntervals:
375                        mps.append(ps[self.targetValue] + cis[self.targetValue])
376                        mps.append(ps[self.targetValue] + 0.0)
377                        mps.append(ps[self.targetValue] - cis[self.targetValue])
378                    else:
379                        mps.extend([ps[self.targetValue]] * 3)
380                cn += 1.0
381
382            ## (re)set the curves
383            if self.variableContinuous:
384                newSymbol = OWPoint.NoSymbol
385            else:
386                newSymbol = OWPoint.Diamond
387               
388            self.probCurveKey.set_data(xs, mps)
389            self.probCurveKey.set_symbol(newSymbol)
390
391            if self.variableContinuous:
392                self.probCurveKey.set_style(OWCurve.Lines)
393                if self.showConfidenceIntervals:
394                    self.probCurveUpperCIKey.setData(xs, ups)
395                    self.probCurveUpperCIKey.set_style(OWCurve.Dots)
396                    self.probCurveLowerCIKey.setData(xs, lps)
397                    self.probCurveLowerCIKey.set_style(OWCurve.Dots)
398            else:
399                if self.showConfidenceIntervals:
400                    self.probCurveKey.set_style(distribErrorBarCurve.DistributionCurve)
401                else:
402                    self.probCurveKey.set_style(OWCurve.Points)
403        else:
404            self.enableYRaxis(0)
405            self.setShowYRaxisTitle(0)
406       
407        self.probCurveKey.setVisible(self.showProbabilities)
408        self.probCurveUpperCIKey.setVisible(self.showConfidenceIntervals and self.showProbabilities)
409        self.probCurveLowerCIKey.setVisible(self.showConfidenceIntervals and self.showProbabilities)
410        self.replot()
411
412class OWDistributionsQt(OWWidget):
413    settingsList = ["numberOfBars", "barSize", "graph.showContinuousClassGraph", "showProbabilities", "showConfidenceIntervals", "smoothLines", "lineWidth", "showMainTitle", "showXaxisTitle", "showYaxisTitle", "showYPaxisTitle"]
414    contextHandlers = {"": DomainContextHandler("", ["attribute", "targetValue", "visibleOutcomes", "mainTitle", "xaxisTitle", "yaxisTitle", "yPaxisTitle"], matchValues=DomainContextHandler.MatchValuesClass)}
415
416    def __init__(self, parent=None, signalManager = None):
417        "Constructor"
418        OWWidget.__init__(self, parent, signalManager, "Distributions (Qt)", TRUE)
419        # settings
420        self.numberOfBars = 5
421        self.barSize = 50
422        self.showContinuousClassGraph=1
423        self.showProbabilities = 1
424        self.showConfidenceIntervals = 0
425        self.smoothLines = 0
426        self.lineWidth = 1
427        self.showMainTitle = 0
428        self.showXaxisTitle = 1
429        self.showYaxisTitle = 1
430        self.showYPaxisTitle = 1
431
432        self.attribute = ""
433        self.targetValue = 0
434        self.visibleOutcomes = []
435        self.outcomes = []
436
437        # tmp values
438        self.mainTitle = ""
439        self.xaxisTitle = ""
440        self.yaxisTitle = "frequency"
441        self.yPaxisTitle = ""
442
443        # GUI
444#        self.tabs = OWGUI.tabWidget(self.controlArea)
445#        self.GeneralTab = OWGUI.createTabPage(self.tabs, "Main")
446#        self.SettingsTab = OWGUI.createTabPage(self.tabs, "Settings")
447        self.GeneralTab = self.SettingsTab = self.controlArea
448
449        self.graph = OWDistributionGraphQt(self, self.mainArea)
450        self.mainArea.layout().addWidget(self.graph)
451        self.graph.setAxisScale(yRight, -0.05, 1.05, 0.1)
452        self.connect(self.graphButton, SIGNAL("clicked()"), self.graph.saveToFile)
453       
454        self.loadSettings()
455        self.setShowXaxisTitle()
456        self.setShowYaxisTitle()
457        self.setShowYPaxisTitle()
458
459        self.barSize = 50
460
461        # inputs
462        # data and graph temp variables
463        self.inputs = [("Data", ExampleTable, self.setData, Default)]
464
465        self.data = None
466        self.outcomenames = []
467        self.probGraphValues = []
468
469        b = OWGUI.widgetBox(self.controlArea, "Variable", addSpace=True)
470        self.variablesQCB = OWGUI.comboBox(b, self, "attribute", valueType = str, sendSelectedValue = True, callback=self.setVariable)
471        OWGUI.widgetLabel(b, "Displayed outcomes")
472        self.outcomesQLB = OWGUI.listBox(b, self, "visibleOutcomes", "outcomes", selectionMode = QListWidget.MultiSelection, callback = self.outcomeSelectionChange)
473
474        # GUI connections
475        # options dialog connections
476#        b = OWGUI.widgetBox(self.SettingsTab, "Bars")
477#        OWGUI.spin(b, self, "numberOfBars", label="Number of bars", min=5, max=60, step=5, callback=self.setNumberOfBars, callbackOnReturn=True)
478#        self.numberOfBarsSlider = OWGUI.hSlider(self.SettingsTab, self, 'numberOfBars', box='Number of bars', minValue=5, maxValue=60, step=5, callback=self.setNumberOfBars, ticks=5)
479#        self.numberOfBarsSlider.setTracking(0) # no change until the user stop dragging the slider
480
481#        self.barSizeSlider = OWGUI.hSlider(self.SettingsTab, self, 'barSize', box="Bar size", minValue=30, maxValue=100, step=5, callback=self.setBarSize, ticks=10)
482#        OWGUI.spin(b, self, "barSize", label="Bar size", min=30, max=100, step=5, callback=self.setBarSize, callbackOnReturn=True)
483
484        box = OWGUI.widgetBox(self.SettingsTab, "General graph settings", addSpace=True)
485        box.setMinimumWidth(180)
486        box2 = OWGUI.widgetBox(box, orientation = "horizontal")
487        OWGUI.checkBox(box2, self, 'showMainTitle', 'Main title', callback = self.setShowMainTitle)
488        OWGUI.lineEdit(box2, self, 'mainTitle', callback = self.setMainTitle, enterPlaceholder=True)
489
490        box3 = OWGUI.widgetBox(box, orientation = "horizontal")
491        OWGUI.checkBox(box3, self, 'showXaxisTitle', 'X axis title', callback = self.setShowXaxisTitle)
492        OWGUI.lineEdit(box3, self, 'xaxisTitle', callback = self.setXaxisTitle, enterPlaceholder=True)
493
494        box4 = OWGUI.widgetBox(box, orientation = "horizontal")
495        OWGUI.checkBox(box4, self, 'showYaxisTitle', 'Y axis title', callback = self.setShowYaxisTitle)
496        OWGUI.lineEdit(box4, self, 'yaxisTitle', callback = self.setYaxisTitle, enterPlaceholder=True)
497
498        OWGUI.checkBox(box, self, 'graph.showContinuousClassGraph', 'Show continuous class graph', callback=self.setShowContinuousClassGraph)
499        OWGUI.spin(box, self, "numberOfBars", label="Number of bars", min=5, max=60, step=5, callback=self.setNumberOfBars, callbackOnReturn=True)
500
501        box5 = OWGUI.widgetBox(self.SettingsTab, "Probability plot")
502        self.showProb = OWGUI.checkBox(box5, self, 'showProbabilities', 'Show probabilities', callback = self.setShowProbabilities)
503        self.targetQCB = OWGUI.comboBox(OWGUI.indentedBox(box5, sep=OWGUI.checkButtonOffsetHint(self.showProb)), self, "targetValue", label="Target value", valueType=int, callback=self.setTarget)
504
505        box6 = OWGUI.widgetBox(box5, orientation = "horizontal")
506
507        self.showYPaxisCheck = OWGUI.checkBox(box6, self, 'showYPaxisTitle', 'Axis title', callback = self.setShowYPaxisTitle)
508        self.yPaxisEdit = OWGUI.lineEdit(box6, self, 'yPaxisTitle', callback = self.setYPaxisTitle, enterPlaceholder=True)
509        self.confIntCheck = OWGUI.checkBox(box5, self, 'showConfidenceIntervals', 'Show confidence intervals', callback = self.setShowConfidenceIntervals)
510        self.cbSmooth = OWGUI.checkBox(box5, self, 'smoothLines', 'Smooth probability lines', callback = self.setSmoothLines)
511        self.showProb.disables = [self.showYPaxisCheck, self.yPaxisEdit, self.confIntCheck, self.targetQCB, self.cbSmooth]
512        self.showProb.makeConsistent()
513
514
515#        self.barSizeSlider = OWGUI.hSlider(box5, self, 'lineWidth', box='Line width', minValue=1, maxValue=9, step=1, callback=self.setLineWidth, ticks=1)
516       
517        OWGUI.rubber(self.SettingsTab)
518
519        #add controls to self.controlArea widget
520
521        self.icons = self.createAttributeIconDict()
522
523        self.graph.numberOfBars = self.numberOfBars
524        self.graph.barSize = self.barSize
525        self.graph.setShowMainTitle(self.showMainTitle)
526        self.graph.setShowXaxisTitle(self.showXaxisTitle)
527        self.graph.setShowYLaxisTitle(self.showYaxisTitle)
528        self.graph.setShowYRaxisTitle(self.showYPaxisTitle)
529        self.graph.setMainTitle(self.mainTitle)
530        self.graph.setXaxisTitle(self.xaxisTitle)
531        self.graph.setYLaxisTitle(self.yaxisTitle)
532        self.graph.setYRaxisTitle(self.yPaxisTitle)
533        self.graph.showProbabilities = self.showProbabilities
534        self.graph.showConfidenceIntervals = self.showConfidenceIntervals
535        self.graph.smoothLines = self.smoothLines
536        self.graph.lineWidth = self.lineWidth
537        #self.graph.variableContinuous = self.VariableContinuous
538        self.graph.targetValue = self.targetValue
539
540    def sendReport(self):
541        self.startReport("%s [%s: %s]" % (self.windowTitle(), self.attribute, self.targetValue))
542        self.reportSettings("Visualized attribute",
543                            [("Attribute", self.attribute),
544                             ("Target class", self.targetValue)])
545        self.reportRaw("<br/>")
546        self.reportImage(self.graph.saveToFileDirect, QSize(600, 400))
547       
548    def setShowMainTitle(self):
549        self.graph.setShowMainTitle(self.showMainTitle)
550
551    def setMainTitle(self):
552        self.graph.setMainTitle(self.mainTitle)
553
554    def setShowXaxisTitle(self):
555        self.graph.setShowXaxisTitle(self.showXaxisTitle)
556
557    def setXaxisTitle(self):
558        self.graph.setXaxisTitle(self.xaxisTitle)
559
560    def setShowYaxisTitle(self):
561        self.graph.setShowYLaxisTitle(self.showYaxisTitle)
562
563    def setYaxisTitle(self):
564        self.graph.setYLaxisTitle(self.yaxisTitle)
565
566    def setShowYPaxisTitle(self):
567        self.graph.setShowYRaxisTitle(self.showYPaxisTitle)
568
569    def setYPaxisTitle(self):
570        self.graph.setYRaxisTitle(self.yPaxisTitle)
571
572    def setBarSize(self):
573        self.graph.setBarSize(self.barSize)
574
575    # Sets whether the probabilities are drawn or not
576    def setShowProbabilities(self):
577        self.graph.showProbabilities = self.showProbabilities
578        self.graph.refreshProbGraph()
579        self.graph.replot()
580
581    def setShowContinuousClassGraph(self):
582        self.graph.refreshPureVisibleOutcomes()
583
584    #Sets the number of bars for histograms of continuous variables
585    def setNumberOfBars(self):
586        self.graph.setNumberOfBars(self.numberOfBars)
587
588    # sets the line smoothing on and off
589    def setSmoothLines(self):
590        #self.SmoothLines = n
591        #self.updateGraphSettings()
592        pass
593
594    # Sets the line thickness for probability
595    def setLineWidth(self):
596        #self.LineWidth = n
597        #self.updateGraphSettings()
598        pass
599
600    # Sets whether the confidence intervals are shown
601    def setShowConfidenceIntervals(self):
602        self.graph.showConfidenceIntervals = self.showConfidenceIntervals
603        #self.updateGraphSettings()
604        self.graph.refreshProbGraph()
605        self.graph.replot()
606
607    def setTarget(self, *t):
608        if t:
609            self.targetValue = t[0]
610        self.graph.setTargetValue(self.targetValue)
611
612    def target(self, targetValue):
613        self.targetValue = targetValue
614        #self.updateGraphSettings()
615        self.graph.refreshProbGraph()
616        self.graph.replot()
617        outcomeName = ""
618        if self.data and self.data.domain.classVar:
619            self.setYPaxisTitle("P( " + self.data.domain.classVar.name + " = " + targetValue + " )")
620
621    def setData(self, data):
622        self.closeContext()
623
624        if data == None:
625            self.variablesQCB.clear()
626            self.targetQCB.clear()
627            self.outcomes = []
628
629            self.graph.setXlabels(None)
630            self.graph.setYLlabels(None)
631            self.graph.setShowYRaxisTitle(0)
632            self.graph.setVisibleOutcomes(None)
633            self.graph.setData(None, None)
634            self.data = None
635            return
636        self.dataHasClass = bool(data.domain.classVar)
637        if self.dataHasClass:
638            self.dataHasDiscreteClass = data.domain.classVar.varType != orange.VarTypes.Continuous
639
640        sameDomain = data and self.data and data.domain == self.data.domain
641
642        if self.dataHasClass and self.dataHasDiscreteClass:
643            self.data = orange.Preprocessor_dropMissingClasses(data)
644        else:
645            self.data = data
646
647        if sameDomain:
648            self.openContext("", self.data)
649            self.graph.setData(self.data, self.graph.attributeName)
650
651        else:
652            self.graph.setData(None, None)
653            self.graph.setTargetValue(None)
654            self.graph.setVisibleOutcomes(None)
655            # set targets
656            self.targetQCB.clear()
657            if self.data.domain.classVar and self.data.domain.classVar.varType == orange.VarTypes.Discrete:
658                self.targetQCB.addItems([val for val in self.data.domain.classVar.values])
659                self.setTarget(0)
660
661            # set variable combo box
662            self.variablesQCB.clear()
663            variables = []
664            for attr in self.data.domain.attributes:
665                if attr.varType in [orange.VarTypes.Discrete, orange.VarTypes.Continuous]:
666                    self.variablesQCB.addItem(self.icons[attr.varType], attr.name)
667                    variables.append(attr)
668
669            if self.data and variables:
670                self.attribute = variables[0].name
671                self.graph.setData(self.data, variables[0].name) # pick first variable
672                #self.setVariable()
673
674            self.targetValue = 0  # self.data.domain.classVar.values.index(str(targetVal))
675            if self.dataHasClass and self.dataHasDiscreteClass:
676                self.graph.setTargetValue(self.targetValue) #str(self.data.domain.classVar.values[0])) # pick first target
677                self.setOutcomeNames(self.data.domain.classVar.values.native())
678            else:
679               self.setOutcomeNames([])
680
681            self.openContext("", self.data)
682            if self.data and variables:
683                self.setVariable()
684
685        for f in [self.setMainTitle, self.setTarget, self.setXaxisTitle, self.setYaxisTitle, self.setYPaxisTitle, self.outcomeSelectionChange]:
686            f()
687
688
689    def setOutcomeNames(self, list):
690        "Sets the outcome target names."
691        colors = ColorPaletteGenerator()
692        self.outcomes = [(ColorPixmap(c), l) for c, l in zip(colors, list)]
693        self.visibleOutcomes = range(len(list))
694
695    def outcomeSelectionChange(self):
696        "Sets which outcome values are represented in the graph."
697        "Reacts to changes in outcome selection."
698        self.graph.visibleOutcomes = [i in self.visibleOutcomes for i in range(self.outcomesQLB.count())]
699        self.graph.refreshVisibleOutcomes()
700        #self.graph.replot()
701        #self.repaint()
702
703    def setVariable(self):
704        self.graph.setVariable(self.attribute)
705        self.graph.refreshVisibleOutcomes()
706        self.xaxisTitle = str(self.attribute)
707        self.repaint()
708
709
710if __name__ == "__main__":
711    a = QApplication(sys.argv)
712    owd = OWDistributionsQt()
713##    a.setMainWidget(owd)
714##    from pywin.debugger import set_trace
715##    set_trace()
716    owd.show()
717    data=orange.ExampleTable("../../doc/datasets/housing.tab")
718    owd.setData(data)
719    a.exec_()
720    owd.saveSettings()
Note: See TracBrowser for help on using the repository browser.