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

Revision 8042:ffcb93bc9028, 6.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 
1from OWGraph import *
2from orngScaleData import *
3from math import sqrt
4
5class OWSieveMultigramGraph(OWGraph, orngScaleData):
6    def __init__(self, parent = None, name = None):
7        "Constructs the graph"
8        OWGraph.__init__(self, parent, name)
9        orngScaleData.__init__(self)
10        self.lineWidth = 5
11        self.minPearson = 2
12        self.maxPearson = 10
13        self.enableXaxis(0)
14        self.enableYLaxis(0)
15        self.setAxisScale(QwtPlot.xBottom, -1.25, 1.25, 1)
16        self.setAxisScale(QwtPlot.yLeft, -1.25, 1.25, 1)
17
18    def setData(self, data):
19        OWGraph.setData(self, data)
20        orngScaleData.setData(self, data)
21
22    def updateData(self, data, labels, probabilities):
23        self.clear()
24        self.tips.removeAll()
25
26        # we must have at least 3 attributes to be able to show anything
27        if len(labels) < 3:
28            self.replot()
29            return
30
31        length = len(labels)
32        indices = []
33        xs = []
34
35        attrNameList = []
36        for attr in data.domain: attrNameList.append(attr.name)
37
38        ###########
39        # create a table of indices that stores the sequence of variable indices
40        for label in labels: indices.append(attrNameList.index(label))
41
42        ###########
43        # create anchor for two edges of every attribute
44        anchors = [[],[]]
45        for i in range(length):
46            x = math.cos(2*math.pi * float(i) / float(length)); strX = "%.4f" % (x)
47            y = math.sin(2*math.pi * float(i) / float(length)); strY = "%.4f" % (y)
48            anchors[0].append(float(strX))  # this might look stupid, but this way we get rid of rounding errors
49            anchors[1].append(float(strY))
50
51        ###########
52        # draw polygon
53        xData = []; yData = []
54        for i in range(len(labels)+1):
55            x = math.cos(2*math.pi * float(i) / float(len(labels)))
56            y = math.sin(2*math.pi * float(i) / float(len(labels)))
57            xData.append(x)
58            yData.append(y)
59        newColor = QColor()
60        newColor.setRgb(0, 0, 0)
61        self.addCurve("", newColor, newColor, 2, QwtPlotCurve.Lines, xData = xData, yData = yData)
62       
63        ###########
64        # draw text at lines
65        for i in range(length):
66            # print attribute name
67            self.addMarker(labels[i], 0.6*(anchors[0][i]+anchors[0][(i+1)%length]), 0.6*(anchors[1][i]+anchors[1][(i+1)%length]), Qt.AlignHCenter | Qt.AlignVCenter, bold = 1)
68           
69            if data.domain[labels[i]].varType == orange.VarTypes.Discrete:
70                # print all possible attribute values
71                values = data.domain[labels[i]].values
72                count = len(values)
73                k = 1.08
74                for j in range(count):
75                    pos = (1.0 + 2.0*float(j)) / float(2*count)
76                    self.addMarker(values[j], k*(1-pos)*anchors[0][i]+k*pos*anchors[0][(i+1)%length], k*(1-pos)*anchors[1][i]+k*pos*anchors[1][(i+1)%length], Qt.AlignHCenter | Qt.AlignVCenter)
77
78        # -----------------------------------------------------------
79        #  create data lines
80        # -----------------------------------------------------------
81        for attrXindex in range(len(labels)):
82            attrXName = labels[attrXindex]
83
84            for attrYindex in range(attrXindex+1, len(labels)):
85                attrYName = labels[attrYindex]
86
87                for valXindex in range(len(data.domain[attrXName].values)):
88                    valX = data.domain[attrXName].values[valXindex]
89
90                    for valYindex in range(len(data.domain[attrYName].values)):
91                        valY = data.domain[attrYName].values[valYindex]
92
93                        ((nameX, countX),(nameY, countY), actual, sum) = probabilities['%s+%s:%s+%s' %(attrXName, valX, attrYName, valY)]
94
95                        # calculate starting and ending coordinates for lines
96                        val = (1.0 + 2.0*float(valXindex)) / float(2*len(data.domain[attrXName].values))
97                        attrXDataAnchorX = anchors[0][attrXindex]*(1-val) + anchors[0][(attrXindex+1)%length]*val
98                        attrXDataAnchorY = anchors[1][attrXindex]*(1-val) + anchors[1][(attrXindex+1)%length]*val
99
100                        val = (1.0 + 2.0*float(valYindex)) / float(2*len(data.domain[attrYName].values))
101                        attrYDataAnchorX = anchors[0][attrYindex]*(1-val) + anchors[0][(attrYindex+1)%length]*val
102                        attrYDataAnchorY = anchors[1][attrYindex]*(1-val) + anchors[1][(attrYindex+1)%length]*val
103
104                        self.addLinePearson([attrXDataAnchorX, attrYDataAnchorX], [attrXDataAnchorY, attrYDataAnchorY], countX, countY, actual, sum)
105        self.replot()
106
107
108    def addLinePearson(self, xDataList, yDataList, countX, countY, actual, sum):
109        expected = float(countX*countY)/float(sum)
110        if actual == expected == 0: return
111        elif expected == 0:     # if expected == 0 we have to solve division by zero. In reverse example (when actual == 0) pearson = -expected/sqrt(expected)
112            pearson = actual/sqrt(actual)
113        else:
114            pearson = (actual - expected) / sqrt(expected)
115
116        if abs(pearson) <= self.minPearson: return       # we don't want to draw white lines
117
118        if pearson > 0:     # if there are more examples that we would expect under the null hypothesis
119            intPearson = min(math.floor(pearson), self.maxPearson)
120            b = 255
121            r = g = 255 - intPearson*200.0/float(self.maxPearson)
122            r = g = max(r, 55)  #
123            penWidth = int(float(intPearson*self.lineWidth)/float(self.maxPearson))
124        elif pearson < 0:
125            intPearson = max(math.ceil(pearson), -self.maxPearson)
126            r = 255
127            b = g = 255 + intPearson*200.0/float(self.maxPearson)
128            b = g = max(b, 55)
129            penWidth = int(float(intPearson*self.lineWidth)/float(-self.maxPearson))
130        color = QColor(r,g,b)
131        key = self.addCurve('', color, color, 0, QwtPlotCurve.Lines, symbol = QwtSymbol.NoSymbol, xData = xDataList, yData = yDataList, lineWidth = penWidth)
132
133
134
135if __name__== "__main__":
136    #Draw a simple graph
137    a = QApplication(sys.argv)
138    c = OWSieveMultigramGraph()
139
140    c.show()
141    a.exec_()
Note: See TracBrowser for help on using the repository browser.