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

📄 owmosaicdisplay.py

📁 orange源码 数据挖掘技术
💻 PY
📖 第 1 页 / 共 4 页
字号:
        # draw rectangles
        self.DrawData(attrList, (xOff, xOff+squareSize), (yOff, yOff+squareSize), 0, "", len(attrList))
        
        self.DrawLegend(data, (xOff, xOff+squareSize), (yOff, yOff+squareSize)) # draw class legend

        self.canvas.update()

    # ############################################################################
    # ############################################################################
    
    ##  DRAW DATA - draw rectangles for attributes in attrList inside rect (x0,x1), (y0,y1)
    def DrawData(self, attrList, (x0, x1), (y0, y1), side, condition, totalAttrs, lastValueForFirstAttribute = 0, usedAttrs = [], usedVals = [], attrVals = ""):
        if self.conditionalDict[attrVals] == 0:
            self.addRect(x0, x1, y0, y1, attrVals = attrVals)
            self.DrawText(side, attrList[0], (x0, x1), (y0, y1), totalAttrs, lastValueForFirstAttribute, attrVals)  # store coordinates for later drawing of labels
            return
        
        attr = attrList[0]
        edge = len(attrList) * self.cellspace  # how much smaller rectangles do we draw
        values = self.attributeValuesDict.get(attr, None) or getVariableValuesSorted(self.data, attr)
        if side%2: values = values[::-1]        # reverse names if necessary

        if side%2 == 0:                                     # we are drawing on the x axis
            whole = max(0, (x1-x0)-edge*(len(values)-1))  # we remove the space needed for separating different attr. values
            if whole == 0: edge = (x1-x0)/float(len(values)-1)
        else:                                               # we are drawing on the y axis
            whole = max(0, (y1-y0)-edge*(len(values)-1))
            if whole == 0: edge = (y1-y0)/float(len(values)-1)

        currPos = 0.0
        if attrVals == "": counts = [self.conditionalDict[val] for val in values]
        else:              counts = [self.conditionalDict[attrVals + "-" + val] for val in values]
        total = sum(counts)
        
        for i in range(len(counts)):
            val = values[i]
            size = whole*float(counts[i])/float(total)            
            htmlVal = getHtmlCompatibleString(val)
            if attrVals != "": newAttrVals = attrVals + "-" + val
            else:              newAttrVals = val

            if side % 2 == 0:   # if drawing horizontal
                if len(attrList) == 1:  self.addRect(x0+currPos, x0+currPos+size, y0, y1, condition + 4*"&nbsp;" + attr + ": <b>" + htmlVal + "</b><br>", usedAttrs + [attr], usedVals + [val], newAttrVals)
                else:                   self.DrawData(attrList[1:], (x0+currPos, x0+currPos+size), (y0, y1), side +1, condition + 4*"&nbsp;" + attr + ": <b>" + htmlVal + "</b><br>", totalAttrs, lastValueForFirstAttribute + int(val == values[-1]), usedAttrs + [attr], usedVals + [val], newAttrVals)
            else:
                if len(attrList) == 1:  self.addRect(x0, x1, y0+currPos, y0+currPos+size, condition + 4*"&nbsp;" + attr + ": <b> " + htmlVal + "</b><br>", usedAttrs + [attr], usedVals + [val], newAttrVals)
                else:                   self.DrawData(attrList[1:], (x0, x1), (y0+currPos, y0+currPos+size), side +1, condition + 4*"&nbsp;" + attr + ": <b>" + htmlVal + "</b><br>", totalAttrs, lastValueForFirstAttribute, usedAttrs + [attr], usedVals + [val], newAttrVals)
            currPos += size + edge

        self.DrawText(side, attrList[0], (x0, x1), (y0, y1), totalAttrs, lastValueForFirstAttribute, attrVals)

   
    ######################################################################
    ## DRAW TEXT - draw legend for all attributes in attrList and their possible values
    def DrawText(self, side, attr, (x0, x1), (y0, y1), totalAttrs, lastValueForFirstAttribute, attrVals):
        if self.drawnSides[side]: return
        #if side == RIGHT and lastValueForFirstAttribute != 2: return
        if side == RIGHT:
            if lastValueForFirstAttribute != 2: return
            elif not self.conditionalDict[attrVals]:
                self.conditionalDict[attrVals] = [1 for i in range(len(getVariableValuesSorted(self.data, attr)))]
        
        if not self.conditionalDict[attrVals]:
            if not self.drawPositions.has_key(side): self.drawPositions[side] = (x0, x1, y0, y1)
            return
        else:
            if self.drawPositions.has_key(side): (x0, x1, y0, y1) = self.drawPositions[side]        # restore the positions where we have to draw the attribute values and attribute name
            
        self.drawnSides[side] = 1

        values = self.attributeValuesDict.get(attr, None) or getVariableValuesSorted(self.data, attr)
        if side % 2:  values = values[::-1]

        width  = x1-x0 - (side % 2 == 0) * self.cellspace*(totalAttrs-side)*(len(values)-1)
        height = y1-y0 - (side % 2 == 1) * self.cellspace*(totalAttrs-side)*(len(values)-1)
        
        #calculate position of first attribute
        if side == 0:    OWCanvasText(self.canvas, attr, x0+(x1-x0)/2, y1 + self.attributeNameOffset, Qt.AlignCenter, bold = 1)
        elif side == 1:  OWCanvasText(self.canvas, attr, x0 - self.attributeNameOffset, y0+(y1-y0)/2, Qt.AlignRight + Qt.AlignVCenter, bold = 1)
        elif side == 2:  OWCanvasText(self.canvas, attr, x0+(x1-x0)/2, y0 - self.attributeNameOffset, Qt.AlignCenter, bold = 1)
        else:            OWCanvasText(self.canvas, attr, x1 + self.attributeNameOffset, y0+(y1-y0)/2, Qt.AlignLeft + Qt.AlignVCenter, bold = 1)
                
        currPos = 0
        if attrVals == "":  counts = [self.conditionalDict.get(val, 1) for val in values]
        else:               counts = [self.conditionalDict.get(attrVals + "-" + val, 1) for val in values]
        total = sum(counts)
        if total == 0:
            counts = [1]*len(values)
            total = sum(counts)

        for i in range(len(values)):
            val = values[i]
            perc = counts[i]/float(total)
            if side == 0:    OWCanvasText(self.canvas, str(val), x0+currPos+width*0.5*perc, y1 + self.attributeValueOffset, Qt.AlignCenter, bold = 0)
            elif side == 1:  OWCanvasText(self.canvas, str(val), x0-self.attributeValueOffset, y0+currPos+height*0.5*perc, Qt.AlignRight + Qt.AlignVCenter, bold = 0)
            elif side == 2:  OWCanvasText(self.canvas, str(val), x0+currPos+width*perc*0.5, y0 - self.attributeValueOffset, Qt.AlignCenter, bold = 0)
            else:            OWCanvasText(self.canvas, str(val), x1+self.attributeValueOffset, y0 + currPos + height*0.5*perc, Qt.AlignLeft + Qt.AlignVCenter, bold = 0)

            if side % 2 == 0: currPos += perc*width + self.cellspace*(totalAttrs-side)
            else :            currPos += perc*height+ self.cellspace*(totalAttrs-side)

            
     # draw the class legend below the square
    def DrawLegend(self, data, (x0, x1), (y0, y1)):
        if self.interiorColoring == CLASS_DISTRIBUTION and (not data.domain.classVar or data.domain.classVar.varType == orange.VarTypes.Continuous): return

        if self.interiorColoring == PEARSON:
            names = ["<-8", "-8:-4", "-4:-2", "-2:2", "2:4", "4:8", ">8", "Residuals:"]
            colors = self.redColors[::-1] + self.blueColors[1:]
        else:
            names = (self.attributeValuesDict.get(data.domain.classVar.name, None) or getVariableValuesSorted(data, data.domain.classVar.name)) + [data.domain.classVar.name+":"]
            colors = [self.colorPalette[i] for i in range(len(data.domain.classVar.values))]
        
        for name in names:
            self.names.append(OWCanvasText(self.canvas, name))
            
        totalWidth = sum([self.names[i].boundingRect().width() for i in range(len(self.names))])

        # compute the x position of the center of the legend
        y = y1 + self.attributeNameOffset + 20
        distance = 30
        startX = (x0+x1)/2 - (totalWidth + (len(names))*distance)/2

        self.names[-1].move(startX+15, y+1); self.names[-1].show()
        xOffset = self.names[-1].boundingRect().width() + distance

        size = 16 # 8 + 8*(self.interiorColoring == PEARSON)
        
        for i in range(len(names)-1):
            if self.interiorColoring == PEARSON: edgeColor = Qt.black
            else: edgeColor = colors[i]

            OWCanvasRectangle(self.canvas, startX + xOffset, y-size/2, size, size, edgeColor, colors[i])
            self.names[i].move(startX + xOffset + 18, y)
            xOffset += distance + self.names[i].boundingRect().width()


    # draw a rectangle, set it to back and add it to rect list                
    def addRect(self, x0, x1, y0, y1, condition = "", usedAttrs = [], usedVals = [], attrVals = ""):
        x0 = int(x0); x1 = int(x1); y0 = int(y0); y1 = int(y1)
        if x0 == x1: x1+=1
        if y0 == y1: y1+=1

        if x1-x0 + y1-y0 == 2: y1+=1        # if we want to show a rectangle of width and height 1 it doesn't show anything. in such cases we therefore have to increase size of one edge

        rect = OWCanvasRectangle(self.canvas, x0, y0, x1-x0, y1-y0, z = 30)

        # we have to remember which conditions were new in this update so that when we right click we can only remove the last added selections
        if self.selectionRectangle != None and rect in self.canvas.collisions(self.selectionRectangle) and not self.selectionConditionsDict.has_key((tuple(usedAttrs), tuple(usedVals))):
            self.recentlyAdded = getattr(self, "recentlyAdded", []) + [(tuple(usedAttrs), tuple(usedVals))]
            self.selectionConditionsDict[(tuple(usedAttrs), tuple(usedVals))] = 1

        # show rectangle selected or not
        if self.selectionConditionsDict.has_key((tuple(usedAttrs), tuple(usedVals))):
            rect.setPen(QPen(Qt.black, 3, Qt.DotLine))

            if self.updateSelectedData: 
                pp = orange.Preprocessor_take()
                for i in range(len(usedAttrs)):
                    pp.values[self.data.domain[usedAttrs[i]]] = usedVals[i]
                tempData = pp(self.data)
                
                if not self.selectedData: self.selectedData = tempData
                else:                     self.selectedData.extend(tempData)

        # if we have selected a rule that contains this combination of attr values then show a kind of selection of this rectangle
        if self.activeRule and len(usedAttrs) == len(self.activeRule[0]) and sum([v in usedAttrs for v in self.activeRule[0]]) == len(self.activeRule[0]):
            for vals in self.activeRule[1]:
                if usedVals == [vals[self.activeRule[0].index(a)] for a in usedAttrs]:
                    values = self.attributeValuesDict.get(self.data.domain.classVar.name, None) or getVariableValuesSorted(self.data, self.data.domain.classVar.name)
                    counts = [self.conditionalDict[attrVals + "-" + val] for val in values]
                    d = 2
                    r = OWCanvasRectangle(self.canvas, x0-d, y0-d, x1-x0+2*d+1, y1-y0+2*d+1, z = 50)
                    r.setPen(QPen(self.colorPalette[counts.index(max(counts))], 2, Qt.DashLine))
               

        if not self.conditionalDict[attrVals]: return rect
        if self.interiorColoring == CLASS_DISTRIBUTION and (not self.data.domain.classVar or not self.data.domain.classVar.varType == orange.VarTypes.Discrete):
            return rect

        aprioriDist = None; pearson = None; expected = None

        # draw pearsons residuals
        if self.interiorColoring == PEARSON or not self.data.domain.classVar or self.data.domain.classVar.varType != orange.VarTypes.Discrete:
            s = sum(self.aprioriDistributions[0])
            expected = s * reduce(lambda x, y: x*y, [self.aprioriDistributions[i][usedVals[i]]/float(s) for i in range(len(usedVals))])
            actual = self.conditionalDict[attrVals]
            pearson = float(actual - expected) / sqrt(expected)
            if abs(pearson) < 2:   ind = 0
            elif abs(pearson) < 4: ind = 1
            elif abs(pearson) < 8: ind = 2
            else:                  ind = 3

            if pearson > 0: color = self.blueColors[ind]
            else: color = self.redColors[ind]
            rect = OWCanvasRectangle(self.canvas, x0, y0, x1-x0, y1-y0, color, color, z = -20)

        # draw class distribution - actual and apriori
        else:
            clsValues = self.attributeValuesDict.get(self.data.domain.classVar.name, None) or getVariableValuesSorted(self.data, self.data.domain.classVar.name)
            aprioriDist = orange.Distribution(self.data.domain.classVar.name, self.data)
            total = 0
            for i in range(len(clsValues)):
                val = self.conditionalDict[attrVals + "-" + clsValues[i]]
                if self.horizontalDistribution:
                    if i == len(clsValues)-1: v = x1-x0 - total
                    else:                       v = int(((x1-x0)* val)/self.conditionalDict[attrVals])
                    OWCanvasRectangle(self.canvas, x0+total, y0, v, y1-y0, self.colorPalette[i], self.colorPalette[i], z = -20)
                else:
                    if i == len(clsValues)-1: v = y1-y0 - total
                    else:                       v = int(((y1-y0)* val)/self.conditionalDict[attrVals])
                    OWCanvasRectangle(self.canvas, x0, y0+total, x1-x0, v, self.colorPalette[i], self.colorPalette[i], z = -20)
                total += v

            # show apriori boxes and lines
            if (self.showAprioriDistributionLines or self.useBoxes) and abs(x1 - x0) > self.boxSize and abs(y1 - y0) > self.boxSize:

⌨️ 快捷键说明

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