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

📄 ownomogramgraph.py

📁 orange源码 数据挖掘技术
💻 PY
📖 第 1 页 / 共 5 页
字号:
        mapped_labels = [self.getVerticalCoordinates(rect,v)-canvas.fontSize/2 for v in self.attValues]
        self.drawVerticalLabel(self, min_mapped, mapped_labels, canvas)
            
        #find and select zero value (beta = 0)
        (propBeta,maxPos,zero) = self.findZeroValue()
        self.selectValues = [[mapper.mapBeta(zero, self),self.getVerticalCoordinates(rect, self.attValues[maxPos-1]), zero]]                
            
        if not self.selectedValue:
            self.selectedValue = self.selectValues[0]            

        # draw lines
        for i in range(len(atValues_mapped)):
            a = self.contValues[i]
            if canvas.parent.histogram:
                a.setPen(QPen(Qt.black, 1+self.attValues[i].lineWidth*canvas.parent.histogram_size))
            else:
                a.setPen(QPen(Qt.black, 2))
            a.setPoints(atValues_mapped[i], self.getVerticalCoordinates(rect, self.attValues[i])-canvas.parent.diff_between_ordinal/2, atValues_mapped[i], self.getVerticalCoordinates(rect, self.attValues[i])+canvas.parent.diff_between_ordinal/2)
            self.selectValues.append([atValues_mapped[i],self.getVerticalCoordinates(rect, self.attValues[i]), self.attValues[i].betaValue])
            if i < len(atValues_mapped)-1:
                a.connection = QCanvasLine(canvas)
                a.connection.setPen(QPen(Qt.black, 1))
                a.connection.setPoints(atValues_mapped[i],
                                       self.getVerticalCoordinates(rect, self.attValues[i])-canvas.parent.diff_between_ordinal/2,
                                       atValues_mapped[i+1],
                                       self.getVerticalCoordinates(rect, self.attValues[i])-canvas.parent.diff_between_ordinal/2)
                a.connection.setPen(QPen(Qt.DotLine))
                a.connection.show()
            # if distance between i and i+1 is large, add some select values.
            x1 = atValues_mapped[i]
            y1 = self.getVerticalCoordinates(rect, self.attValues[i])-canvas.parent.diff_between_ordinal/2
            x2 = atValues_mapped[i]
            y2 = self.getVerticalCoordinates(rect, self.attValues[i])+canvas.parent.diff_between_ordinal/2
            
            n = int(y2-y1)/5-1
            self.selectValues = self.selectValues + [[x1, y1+(float(j+1)/float(n+1))*(y2-y1), self.attValues[i].betaValue] for j in range(n)]
            a.show()
        
    
    def paint2d(self, canvas, rect, mapper):
        self.initializeBeforePaint(canvas)

        # get all values tranfsormed with current mapper 
        atValues_mapped, atErrors_mapped, min_mapped, max_mapped = mapper(self) # return mapped values, errors, min, max --> mapper(self)

        # draw a bounding box
        self.drawBox(min_mapped, max_mapped+1, rect)

        # if fixedDistance:
        self.paint2d_fixedDistance(canvas, rect, mapper)
        

        self.updateValue()
        self.box.show()
        self.label.show()


# #################################################################### 
# Header CANVAS
# ####################################################################
class BasicNomogramHeader(QCanvas):
    def __init__(self, nomogram, parent):
        apply(QCanvas.__init__,(self, parent, ""))
        self.fontSize = parent.fontSize
        self.headerAttrLine = None
        self.nomogram = nomogram
        self.parent = parent
       
    def paintHeader(self, rect, mapper):
        #if self.headerAttrLine:
        #    self.headerAttrLine.destroy()
        [item.setCanvas(None) for item in self.allItems()]

        self.headerAttrLine = mapper.getHeaderLine(self, rect)
        self.headerAttrLine.name = self.nomogram.parent.pointsName[self.nomogram.parent.yAxis]
        self.headerAttrLine.paint(self, rect, mapper)
        self.resize(self.nomogram.pright, rect.height()+16)
        self.update()


# #################################################################### 
# FOOTER CANVAS, sum and probability 
# ####################################################################
class BasicNomogramFooter(QCanvas):
    def __init__(self, nomogram, parent):
        apply(QCanvas.__init__,(self, parent, ""))
        self.fontSize = parent.fontSize
        self.headerAttrLine = None
        self.nomogram = nomogram
        self.footer = None
        self.footerPercent = None
        self.parent = parent
        if self.parent.cl:
            self.footerPercentName = "P(%s=\"%s\")" % (self.parent.cl.domain.classVar.name,self.parent.cl.domain.classVar.values[self.parent.TargetClassIndex])
        else:
            self.footerPercentName = ""
        self.connectedLine = QCanvasLine(self)
        self.connectedLine.setPen(QPen(Qt.blue))
        self.errorLine = QCanvasLine(self)
        
        self.errorPercentLine = QCanvasLine(self)
        self.leftArc = QCanvasPolygon(self)
        self.rightArc = QCanvasPolygon(self)
        self.leftPercentArc = QCanvasPolygon(self)
        self.rightPercentArc = QCanvasPolygon(self)
        self.cilist = [self.errorLine, self.errorPercentLine, self.leftArc, self.rightArc, self.leftPercentArc, self.rightPercentArc]
        for obj in self.cilist:
            obj.setPen(QPen(Qt.blue, 3))
            obj.setZ(100)
        
    def convertToPercent(self, atLine):
        minPercent = math.exp(atLine.minValue)/(1+math.exp(atLine.minValue))
        maxPercent = math.exp(atLine.maxValue)/(1+math.exp(atLine.maxValue))

        percentLine = AttrLine(atLine.name, self)
        percentList = filter(lambda x:x>minPercent and x<maxPercent,Numeric.arange(0, maxPercent+0.1, 0.05))
        for p in percentList:
            if int(10*p) != round(10*p,1) and not p == percentList[0] and not p==percentList[len(percentList)-1]:
                percentLine.addAttValue(AttValue(" "+str(p)+" ", math.log(p/max(1-p,aproxZero)), markerWidth = 1, enable = False))
            else:
                percentLine.addAttValue(AttValue(" "+str(p)+" ", math.log(p/max(1-p,aproxZero)), markerWidth = 1))
        return percentLine  
        
       
    def paintFooter(self, rect, alignType, yAxis, mapper):
        # set height for each scale        
        height = rect.height()/3
        
        # get min and maximum sum, min and maximum beta
        # min beta <--> min sum! , same for maximum
        maxSum = minSum = maxSumBeta = minSumBeta = 0
        for at in self.nomogram.attributes:
            maxSum += mapper.getMaxValue(at)
            minSum += mapper.getMinValue(at)
            maxSumBeta += at.maxValue
            minSumBeta += at.minValue

        # add constant to betas!
        maxSumBeta += self.nomogram.constant.betaValue
        minSumBeta += self.nomogram.constant.betaValue

        # show only reasonable values
        k = (maxSum-minSum)/max((maxSumBeta-minSumBeta),aproxZero)
        if maxSumBeta>4:
            maxSum = (4 - minSumBeta)*k + minSum
            maxSumBeta = 4
        if minSumBeta>3:
            minSum = (3 - minSumBeta)*k + minSum
            minSumBeta = 3
        if minSumBeta<-4:
            minSum = (-4 - minSumBeta)*k + minSum
            minSumBeta = -4
        if maxSumBeta<-3:
            maxSum = (-3 - minSumBeta)*k + minSum
            maxSumBeta = -3

        # draw continous line with values from min and max sum (still have values!)
        self.m = Mapper_Linear_Fixed(minSumBeta, maxSumBeta, rect.left(), rect.right(), maxLinearValue = maxSum, minLinearValue = minSum)
        if self.footer:
            [item.setCanvas(None) for item in self.allItems()]
            #self.footer.destroy()
        self.footer = self.m.getHeaderLine(self, QRect(rect.left(), rect.top(), rect.width(), height))
        self.footer.name = self.nomogram.parent.totalPointsName[self.nomogram.parent.yAxis]

        self.footer.paint(self, QRect(rect.left(), rect.top(), rect.width(), height), self.m)

        # continous line convert to percent and draw accordingly (minbeta = minsum)
        #if self.footerPercent:
        #    self.footerPercent.destroy()

        self.footerPercent = self.convertToPercent(self.footer)

        # create a mapper for footer, BZ CHANGE TO CONSIDER THE TARGET
        self.footerPercent.name = self.footerPercentName
        self.footerPercent.paint(self, QRect(rect.left(), rect.top()+height, rect.width(), 2*height), self.m)                         

        self.resize(self.nomogram.pright, rect.height()+30)
        self.update()
        
    def updateMarkers(self):
        # finds neares beta; use only discrete data
        def getNearestAtt(selectedBeta, at):
            nearestLeft = filter(lambda x: x.betaValue == max([v.betaValue for v in filter(lambda x: x.betaValue <= selectedBeta, at.attValues)]) ,at.attValues)[0]
            nearestRight = filter(lambda x: x.betaValue == min([v.betaValue for v in filter(lambda x: x.betaValue >= selectedBeta, at.attValues)]) ,at.attValues)[0]
            return (nearestLeft, nearestRight)
        
        sum = self.nomogram.constant.betaValue
        for at in self.nomogram.attributes:
            sum += at.selectedValue[2]

        variance = math.pow(self.nomogram.constant.error,2)
        for at in self.nomogram.attributes:
#            if not isinstance(at, AttrLineCont):
            if at.selectedValue[2] == 0.0 and self.parent.alignType == 1:
                continue
            (nleft, nright) = getNearestAtt(at.selectedValue[2], at)
            if nright.betaValue>nleft.betaValue:
                prop = (at.selectedValue[2]-nleft.betaValue)/(nright.betaValue-nleft.betaValue)
            else:
                prop = 0
            if prop == 0:
                variance += math.pow(nleft.error, 2)
            elif prop == 1:
                variance += math.pow(nright.error, 2)
            else:
                variance += math.pow(nleft.error, 2)*(1-prop)
                variance += math.pow(nright.error, 2)*prop

        standard_error = math.sqrt(variance)

        ax=self.m.mapBeta(sum, self.footer)
        # get CI
        ax_maxError = self.m.mapBeta(sum+standard_error*norm_factor(1-((1-float(self.parent.confidence_percent)/100.)/2.)), self.footer)
        ax_minError = self.m.mapBeta(sum-standard_error*norm_factor(1-((1-float(self.parent.confidence_percent)/100.)/2.)), self.footer)
        a = QPointArray()
        a.makeArc(ax_minError, self.footer.marker.y()+10, 10, 10, 0, 180*16)
        self.leftArc.setPoints(a)
        #self.leftArc.setBrush(QBrush(Qt.blue))
    
        a = QPointArray()
        a.makeArc(ax_maxError-10, self.footer.marker.y()-5, 10, 10, 90*16, -90*16)
        self.rightArc.setPoints(a)
        a.makeArc(ax_minError, self.footerPercent.marker.y()-5, 10, 10, 90*16, 180*16)
        self.leftPercentArc.setPoints(a)
        a.makeArc(ax_maxError-10, self.footerPercent.marker.y()-5, 10, 10, 90*16, -90*16)
        self.rightPercentArc.setPoints(a)

        
        axPercentMin=self.m.mapBeta(self.footerPercent.minValue, self.footer)
        axPercentMax=self.m.mapBeta(self.footerPercent.maxValue, self.footer)
        axMin=self.m.mapBeta(self.footer.minValue, self.footer)
        axMax=self.m.mapBeta(self.footer.maxValue, self.footer)

        ax = max(ax, axMin)
        ax = min(ax, axMax)
        self.errorLine.setPoints(ax_minError, self.footer.marker.y(), ax_maxError, self.footer.marker.y())
        self.errorLine.setCanvas(self)
        ax_minError = min(ax_minError, axPercentMax)
        ax_minError = max(ax_minError, axPercentMin)        
        ax_maxError = min(ax_maxError, axPercentMax)
        ax_maxError = max(ax_maxError, axPercentMin)        
        
        self.errorPercentLine.setCanvas(self)
        self.errorPercentLine.setPoints(ax_minError, self.footerPercent.marker.y(), ax_maxError, self.footerPercent.marker.y())
        
        self.footer.selectedValue = [ax,self.footer.marker.y(),self.m.mapBetaToLinear(sum, self.footer)]
        self.footer.marker.setPos(ax, self.footer.marker.y())

        if ax>axPercentMax:
            ax=axPercentMax
        if ax<axPercentMin:
            ax=axPercentMin
        self.footerPercent.selectedValue = [ax,self.footer.marker.y(),1/(1+math.exp(-sum))]
        self.footerPercent.marker.setPos(ax, self.footerPercent.marker.y())
        
        if self.parent.probability:
            self.footer.marker.show()
            self.footerPercent.marker.show()
            if self.footer.marker.x() == self.footerPercent.marker.x():
                self.connectedLine.setPoints(self.footer.marker.x(), self.footer.marker.y(), self.footerPercent.marker.x(), self.footerPercent.marker.y())
                self.connectedLine.setCanvas(self)
                self.connectedLine.show()
            else:
                self.connectedLine.hide()
            if self.parent.confidence_check:
                self.showCI()
            else:
                self.hideCI()
        self.update()
        
    def showCI(self):
        self.errorLine.show()
        self.errorPercentLine.show()

    def hideCI(self):
        self.errorLine.hide()
        self.errorPercentLine.hide()
        self.leftArc.hide()
        self.rightArc.hide()
        self.leftPercentArc.hide()
        self.rightPercentArc.hide()


# #################################################################### 
# Main CANVAS
# ####################################################################

⌨️ 快捷键说明

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