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

📄 owsievemultigramgraph.py

📁 orange源码 数据挖掘技术
💻 PY
字号:
from OWGraph import *
from orngScaleData import *

###########################################################################################
##### CLASS : OWSieveMultigram graph
###########################################################################################
class OWSieveMultigramGraph(OWGraph, orngScaleData):
    def __init__(self, parent = None, name = None):
        "Constructs the graph"
        OWGraph.__init__(self, parent, name)
        orngScaleData.__init__(self)
        self.maxLineWidth = 5
        self.pearsonMinRes = 2
        self.pearsonMaxRes = 10

    def setSettings(self, maxLineWidth, pearsonMinRes, pearsonMaxRes):
        self.maxLineWidth = maxLineWidth
        self.pearsonMaxRes = pearsonMaxRes
        self.pearsonMinRes = pearsonMinRes

    def setData(self, data):
        OWGraph.setData(self, data)
        orngScaleData.setData(self, data)

    #
    # update shown data. Set labels, coloring by className ....
    #
    def updateData(self, data, labels, probabilities, statusBar):
        self.removeCurves()
        self.removeMarkers()
        self.tips.removeAll()

        self.statusBar = statusBar        

        self.setAxisScaleDraw(QwtPlot.xBottom, HiddenScaleDraw())
        self.setAxisScaleDraw(QwtPlot.yLeft, HiddenScaleDraw())
        scaleDraw = self.axisScaleDraw(QwtPlot.xBottom)
        scaleDraw.setOptions(0) 
        scaleDraw.setTickLength(0, 0, 0) 
        scaleDraw = self.axisScaleDraw(QwtPlot.yLeft)
        scaleDraw.setOptions(0) 
        scaleDraw.setTickLength(0, 0, 0) 
        
        self.setAxisScale(QwtPlot.xBottom, -1.25, 1.25, 1)
        self.setAxisScale(QwtPlot.yLeft, -1.25, 1.25, 1)

        # we must have at least 3 attributes to be able to show anything
        if len(labels) < 3: return


        length = len(labels)
        indices = []
        xs = []

        attrNameList = []
        for attr in data.domain: attrNameList.append(attr.name)
    
        ###########
        # create a table of indices that stores the sequence of variable indices
        for label in labels: indices.append(attrNameList.index(label))

        ###########
        # create anchor for two edges of every attribute
        anchors = [[],[]]
        for i in range(length):
            x = math.cos(2*math.pi * float(i) / float(length)); strX = "%.4f" % (x)
            y = math.sin(2*math.pi * float(i) / float(length)); strY = "%.4f" % (y)
            anchors[0].append(float(strX))  # this might look stupid, but this way we get rid of rounding errors
            anchors[1].append(float(strY))

        ###########
        # draw polygon
        xData = []; yData = []
        for i in range(len(labels)+1):
            x = math.cos(2*math.pi * float(i) / float(len(labels)))
            y = math.sin(2*math.pi * float(i) / float(len(labels)))
            xData.append(x)
            yData.append(y)
        newCurveKey = self.insertCurve("polygon")
        newColor = QColor()
        newColor.setRgb(0, 0, 0)
        self.setCurveStyle(newCurveKey, QwtCurve.Lines)
        self.setCurveData(newCurveKey, xData, yData) 

        ###########
        # draw text at lines
        for i in range(length):
            # print attribute name
            mkey = self.insertMarker(labels[i])
            self.marker(mkey).setXValue(0.6*(anchors[0][i]+anchors[0][(i+1)%length]))
            self.marker(mkey).setYValue(0.6*(anchors[1][i]+anchors[1][(i+1)%length]))
            self.marker(mkey).setLabelAlignment(Qt.AlignHCenter + Qt.AlignVCenter)
            font = self.marker(mkey).font(); font.setBold(1); self.marker(mkey).setFont(font)


            if data.domain[labels[i]].varType == orange.VarTypes.Discrete:
                # print all possible attribute values
                values = data.domain[labels[i]].values
                count = len(values)
                k = 1.08
                for j in range(count):
                    pos = (1.0 + 2.0*float(j)) / float(2*count)
                    mkey = self.insertMarker(values[j])
                    self.marker(mkey).setXValue(k*(1-pos)*anchors[0][i]+k*pos*anchors[0][(i+1)%length])
                    self.marker(mkey).setYValue(k*(1-pos)*anchors[1][i]+k*pos*anchors[1][(i+1)%length])
                    self.marker(mkey).setLabelAlignment(Qt.AlignHCenter + Qt.AlignVCenter)

        # -----------------------------------------------------------
        #  create data lines
        # -----------------------------------------------------------
        for attrXindex in range(len(labels)):
            attrXName = labels[attrXindex]

            for attrYindex in range(attrXindex+1, len(labels)):
                attrYName = labels[attrYindex]

                for valXindex in range(len(data.domain[attrXName].values)):
                    valX = data.domain[attrXName].values[valXindex]

                    for valYindex in range(len(data.domain[attrYName].values)):
                        valY = data.domain[attrYName].values[valYindex]

                        ((nameX, countX),(nameY, countY), actual, sum) = probabilities['%s+%s:%s+%s' %(attrXName, valX, attrYName, valY)]

                        # calculate starting and ending coordinates for lines
                        val = (1.0 + 2.0*float(valXindex)) / float(2*len(data.domain[attrXName].values))                    
                        attrXDataAnchorX = anchors[0][attrXindex]*(1-val) + anchors[0][(attrXindex+1)%length]*val
                        attrXDataAnchorY = anchors[1][attrXindex]*(1-val) + anchors[1][(attrXindex+1)%length]*val

                        val = (1.0 + 2.0*float(valYindex)) / float(2*len(data.domain[attrYName].values))                    
                        attrYDataAnchorX = anchors[0][attrYindex]*(1-val) + anchors[0][(attrYindex+1)%length]*val
                        attrYDataAnchorY = anchors[1][attrYindex]*(1-val) + anchors[1][(attrYindex+1)%length]*val

                        self.addLinePearson([attrXDataAnchorX, attrYDataAnchorX], [attrXDataAnchorY, attrYDataAnchorY], countX, countY, actual, sum)


    def addLinePearson(self, xDataList, yDataList, countX, countY, actual, sum):
        expected = float(countX*countY)/float(sum)
        if actual == expected == 0: return
        elif expected == 0:     # if expected == 0 we have to solve division by zero. In reverse example (when actual == 0) pearson = -expected/sqrt(expected)
            pearson = actual/sqrt(actual)
        else:
            pearson = (actual - expected) / sqrt(expected)

        if abs(pearson) < self.pearsonMinRes: return # we don't want to draw white lines
        
        if pearson > 0:     # if there are more examples that we would expect under the null hypothesis
            intPearson = min(math.floor(pearson), self.pearsonMaxRes)
            b = 255
            r = g = 255 - intPearson*200.0/float(self.pearsonMaxRes)
            r = g = max(r, 55)  #
            penWidth = int(float(intPearson*self.maxLineWidth)/float(self.pearsonMaxRes))
        elif pearson < 0:
            intPearson = max(math.ceil(pearson), -self.pearsonMaxRes)
            r = 255
            b = g = 255 + intPearson*200.0/float(self.pearsonMaxRes)
            b = g = max(b, 55)
            penWidth = int(float(intPearson*self.maxLineWidth)/float(-self.pearsonMaxRes))
        color = QColor(r,g,b)
        
        #print penWidth
        key = self.addCurve('line', color, color, 0, QwtCurve.Lines, symbol = QwtSymbol.None)
        pen = QPen(color, penWidth)
        self.setCurvePen(key, pen)
        self.setCurveData(key, xDataList, yDataList)

            
if __name__== "__main__":
    #Draw a simple graph
    a = QApplication(sys.argv)        
    c = OWSieveMultigramGraph()
        
    a.setMainWidget(c)
    c.show()
    a.exec_loop()

⌨️ 快捷键说明

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