⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 owparallelgraph.py

📁 orange源码 数据挖掘技术
💻 PY
📖 第 1 页 / 共 2 页
字号:
                    continue  # only for continuous attributes
                array = Numeric.compress(Numeric.equal(self.validDataArray[indices[i]], 1), self.scaledData[indices[i]])  # remove missing values
                
                if classNameIndex == -1 or continuousClass:    # no class
                    if self.showStatistics == MEANS:
                        m = mean(array)
                        dev = std(array)
                        data.append([(m-dev, m, m+dev)])
                    elif self.showStatistics == MEDIAN:
                        sorted = Numeric.sort(array)
                        data.append([(sorted[int(len(sorted)/4.0)], sorted[int(len(sorted)/2.0)], sorted[int(len(sorted)*0.75)])])
                else:
                    curr = []
                    classValues = getVariableValuesSorted(self.rawdata, self.rawdata.domain.classVar.name)
                    for c in range(len(classValues)):
                        scaledVal = ((classValueIndices[classValues[c]] * 2) + 1) / float(2*len(classValueIndices))
                        nonMissingValues = Numeric.compress(Numeric.equal(self.validDataArray[indices[i]], 1), self.noJitteringScaledData[classNameIndex])  # remove missing values
                        arr_c = Numeric.compress(Numeric.equal(nonMissingValues, scaledVal), array)
                        if len(arr_c) == 0:
                            curr.append(()); continue
                        if self.showStatistics == MEANS:
                            m = mean(arr_c)
                            dev = std(arr_c)
                            curr.append((m-dev, m, m+dev))
                        elif self.showStatistics == MEDIAN:
                            sorted = Numeric.sort(arr_c)
                            curr.append((sorted[int(len(arr_c)/4.0)], sorted[int(len(arr_c)/2.0)], sorted[int(len(arr_c)*0.75)]))
                    data.append(curr)

            # draw vertical lines
            for i in range(len(data)):
                for c in range(len(data[i])):
                    if data[i][c] == (): continue
                    x = i - 0.03*(len(data[i])-1)/2.0 + c*0.03
                    col = self.discPalette[c]
                    self.nonDataKeys.append(self.addCurve("", col, col, 3, QwtCurve.Lines, QwtSymbol.Diamond, xData = [x,x,x], yData = [data[i][c][0], data[i][c][1], data[i][c][2]], lineWidth = 4))
                    self.nonDataKeys.append(self.addCurve("", col, col, 1, QwtCurve.Lines, QwtSymbol.None, xData = [x-0.03, x+0.03], yData = [data[i][c][0], data[i][c][0]], lineWidth = 4))
                    self.nonDataKeys.append(self.addCurve("", col, col, 1, QwtCurve.Lines, QwtSymbol.None, xData = [x-0.03, x+0.03], yData = [data[i][c][1], data[i][c][1]], lineWidth = 4))
                    self.nonDataKeys.append(self.addCurve("", col, col, 1, QwtCurve.Lines, QwtSymbol.None, xData = [x-0.03, x+0.03], yData = [data[i][c][2], data[i][c][2]], lineWidth = 4))

            # draw lines with mean/median values
            classCount = 1
            if classNameIndex == -1 or continuousClass:    classCount = 1 # no class
            else: classCount = len(self.rawdata.domain.classVar.values)
            for c in range(classCount):
                diff = - 0.03*(classCount-1)/2.0 + c*0.03
                ys = []
                xs = []
                for i in range(len(data)):
                    if data[i] != [()]: ys.append(data[i][c][1]); xs.append(i+diff)
                    else:
                        if len(xs) > 1: self.nonDataKeys.append(self.addCurve("", self.discPalette[c], self.discPalette[c], 1, QwtCurve.Lines, QwtSymbol.None, xData = xs, yData = ys, lineWidth = 4))
                        xs = []; ys = []
                self.nonDataKeys.append(self.addCurve("", self.discPalette[c], self.discPalette[c], 1, QwtCurve.Lines, QwtSymbol.None, xData = xs, yData = ys, lineWidth = 4))

        
        # ##################################################
        # show labels in the middle of the axis
        if midLabels:
            for j in range(len(midLabels)):
                mkey = self.insertMarker(midLabels[j])
                self.marker(mkey).setXValue(j+0.5)
                self.marker(mkey).setYValue(1.0)
                self.marker(mkey).setLabelAlignment(Qt.AlignCenter + Qt.AlignTop)

        # show the legend
        if self.enabledLegend == 1 and self.rawdata.domain.classVar:
            if self.rawdata.domain.classVar.varType == orange.VarTypes.Discrete:
                varValues = getVariableValuesSorted(self.rawdata, self.rawdata.domain.classVar.name)
                self.addCurve("<b>" + self.rawdata.domain.classVar.name + ":</b>", QColor(0,0,0), QColor(0,0,0), 0, symbol = QwtSymbol.None, enableLegend = 1)
                for ind in range(len(varValues)):
                    self.addCurve(varValues[ind], self.discPalette[ind], self.discPalette[ind], 15, symbol = QwtSymbol.Rect, enableLegend = 1)
            else:
                l = len(attributes)-1
                xs = [l*1.15, l*1.20, l*1.20, l*1.15]
                count = 200
                for i in range(count):
                    y = i/float(count)
                    col = self.contPalette[y]
                    curve = PolygonCurve(self, QPen(col), QBrush(col))
                    newCurveKey = self.insertCurve(curve)
                    self.nonDataKeys.append(newCurveKey)
                    self.setCurveData(newCurveKey, xs, [y,y, y+height, y+height])

                # add markers for min and max value of color attribute
                [minVal, maxVal] = self.attrValues[self.rawdata.domain.classVar.name]
                decimals = self.rawdata.domain.classVar.numberOfDecimals
                self.addMarker("%%.%df" % (decimals) % (minVal), xs[0] - l*0.02, 0.04, Qt.AlignLeft)
                self.addMarker("%%.%df" % (decimals) % (maxVal), xs[0] - l*0.02, 1.0 - 0.04, Qt.AlignLeft)


    # ##########################################
    # SHOW DISTRIBUTION BAR GRAPH
    def showDistributionValues(self, targetValue, validData, indices, dataStop):
        # get index of class         
        classNameIndex = self.attributeNameIndex[self.rawdata.domain.classVar.name]

        # create color table            
        count = len(self.rawdata.domain.classVar.values)
        #if count < 1: count = 1.0

        # we create a hash table of possible class values (happens only if we have a discrete class)
        classValueIndices = getVariableValueIndices(self.rawdata, self.rawdata.domain.classVar.name)
        classValueSorted  = getVariableValuesSorted(self.rawdata, self.rawdata.domain.classVar.name)

        self.toolInfo = []        
        for graphAttrIndex in range(len(indices)):
            index = indices[graphAttrIndex]
            if self.rawdata.domain[index].varType != orange.VarTypes.Discrete: continue
            attr = self.rawdata.domain[index]
            attrLen = len(attr.values)
            
            values = []
            totals = [0] * attrLen

            # we create a hash table of variable values and their indices
            variableValueIndices = getVariableValueIndices(self.rawdata, index)
            variableValueSorted = getVariableValuesSorted(self.rawdata, index)
            
            for i in range(count):
                values.append([0] * attrLen)

            stop = indices[:graphAttrIndex]
            for i in range(len(self.rawdata)):
                if dataStop and self.hidePureExamples == 1 and dataStop[i] in stop: continue
                if validData[i] == 0: continue
                # processing for distributions
                attrIndex = variableValueIndices[self.rawdata[i][index].value]
                classIndex = classValueIndices[self.rawdata[i][classNameIndex].value]
                totals[attrIndex] += 1
                values[classIndex][attrIndex] += 1

            # calculate maximum value of all values - needed for scaling
            maximum = 1
            for i in range(len(values)):
                for j in range(len(values[i])):
                    if values[i][j] > maximum: maximum = values[i][j]

            # calculate the sum of totals - needed for tooltips
            sumTotals = 0
            for val in totals: sumTotals += val

            # save info for tooltips
            for i in range(attrLen):
                list= []
                for j in range(count):
                    list.append((classValueSorted[j], values[j][i]))
                list.reverse()
                y_start = float(i+1)/float(attrLen); y_end = float(i)/float(attrLen)
                x_start = float(graphAttrIndex) - 0.45; x_end = float(graphAttrIndex) + 0.45
                item = (self.rawdata.domain[index].name, variableValueSorted[i], totals[i], sumTotals, list, (x_start,x_end), (y_start, y_end))
                self.toolInfo.append(item)


            # create bar curve
            for i in range(count):
                if targetValue != None:
                    if classValueSorted[i] == targetValue: newColor = self.colorTargetValue
                    else: newColor = self.colorNonTargetValue
                else:
                    newColor = self.discPalette[i]

                for j in range(attrLen):
                    width = float(values[i][j]*0.5) / float(maximum)
                    interval = 1.0/float(2*attrLen)
                    yOff = float(1.0 + 2.0*j)/float(2*attrLen)
                    height = 0.7/float(count*attrLen)

                    yLowBott = yOff - float(count*height)/2.0 + i*height
                    ckey = self.insertCurve(PolygonCurve(self, pen = QPen(newColor), brush = QBrush(newColor), xData = [graphAttrIndex, graphAttrIndex + width, graphAttrIndex + width, graphAttrIndex], yData = [yLowBott, yLowBott, yLowBott + height, yLowBott + height]))
                    self.nonDataKeys.append(ckey)

        self.addTooltips()
        
    def addTooltips(self):
        for i in range(len(self.toolInfo)):
            (name, value, total, sumTotals, lista, (x_start,x_end), (y_start, y_end)) = self.toolInfo[i]
            if total == 0: continue
            tooltipText = "Attribute: <b>%s</b><br>Value: <b>%s</b><br>Total instances: <b>%i</b> (%.1f%%)<br>Class distribution:<br>" % (name, value, total, 100.0*float(total)/float(sumTotals))
            for j in range(len(lista)):
                (val, count) = lista[j]
                tooltipText += "<b>%s</b> : <b>%i</b> (%.1f%%)" % (val, count, 100.0*float(count)/float(total))
                if j != len(lista)-1 : tooltipText += "<br>"
            x_1 = self.transform(QwtPlot.xBottom, x_start)
            x_2 = self.transform(QwtPlot.xBottom, x_end)
            y_1 = self.transform(QwtPlot.yLeft, y_start)
            y_2 = self.transform(QwtPlot.yLeft, y_end)
            rect = QRect(x_1, y_1, x_2-x_1, y_2-y_1)
            self.toolRects.append(rect)            
            QToolTip.add(self, rect, tooltipText)

    def removeTooltips(self):
        for rect in self.toolRects:
            QToolTip.remove(self, rect)
        self.toolRects = []


    # if user clicked between two lines send signal that 
    def staticMouseClick(self, e):
        if self.parallelDlg:
            x1 = int(self.invTransform(QwtPlot.xBottom, e.x()))
            axis = self.axisScaleDraw(QwtPlot.xBottom)
            self.parallelDlg.sendAttributeSelection([str(axis.label(x1)), str(axis.label(x1+1))])

    def updateLayout(self):
        OWGraph.updateLayout(self)
        self.removeTooltips()
        self.addTooltips()

    """
    def updateAxes(self):
        OWGraph.updateAxes()        
        self.removeTooltips()
        self.addTooltips()
    """
    def updateTooltips(self):
        self.removeTooltips()
        self.addTooltips()

    # if we zoomed, we have to update tooltips    
    def onMouseReleased(self, e):
        OWGraph.onMouseReleased(self, e)
        self.updateTooltips()

    def onMouseMoved(self, e):
        if self.mouseCurrentlyPressed:
            OWGraph.onMouseMoved(self, e)
            return
        else:
            (key, foo1, x, y, foo2) = self.closestCurve(e.pos().x(), e.pos().y())
            dist = abs(x-self.invTransform(QwtPlot.xBottom, e.x())) + abs(y-self.invTransform(QwtPlot.yLeft, e.y()))

            if self.lineTracking:
                if (dist >= 0.1 or key != self.lastSelectedKey) and self.lastSelectedKey not in self.nonDataKeys:
                    existingPen = self.curvePen(self.lastSelectedKey)
                    existingPen.setWidth(1)
                    self.setCurvePen(self.lastSelectedKey, existingPen)
                    self.lastSelectedKey = -1

                if dist < 0.1 and key != self.lastSelectedKey and key not in self.nonDataKeys:
                    self.lastSelectedKey = key
                    existingPen = self.curvePen(self.lastSelectedKey)
                    existingPen.setWidth(3)
                    self.setCurvePen(self.lastSelectedKey, existingPen)
                    
            else:
                OWGraph.onMouseMoved(self, e)
                return
            
            OWGraph.onMouseMoved(self, e)
            self.replot()

    def getSelectionsAsExampleTables(self, targetValue = None):
        if not self.rawdata:
            return (None, None)
        if self.selectionCurveKeyList == []:
            return (None, self.rawdata)
        
        selIndices = []
        unselIndices = range(len(self.rawdata))

        for i in range(len(self.curvePoints)):
            for j in range(len(self.curvePoints[i])):
                if self.isPointSelected(j, self.curvePoints[i][j]):
                    if targetValue and targetValue != int(self.rawdata[i].getclass()): continue
                    selIndices.append(i)
                    unselIndices.pop(i)
            
        selected = self.rawdata.getitemsref(selIndices)
        unselected = self.rawdata.getitemsref(unselIndices)
        
        if len(selected) == 0: selected = None
        if len(unselected) == 0: unselected = None

        return (selected, unselected)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -