source: orange/orange/OrangeWidgets/Visualize/OWDistributions.py @ 8042:ffcb93bc9028

Revision 8042:ffcb93bc9028, 31.1 KB checked in by markotoplak, 3 years ago (diff)

Hierarchical clustering: also catch RuntimeError when importing matplotlib (or the documentation could not be built on server).

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