📄 owpolyvizgraph.py
字号:
from OWGraph import *
from copy import copy, deepcopy
import time, math
from OWkNNOptimization import *
from orngScalePolyvizData import *
import orngVisFuncts
#import orange
# ####################################################################
# get a list of all different permutations
def getPermutationList(elements, tempPerm, currList, checkReverse):
for i in range(len(elements)):
el = elements[i]
elements.remove(el)
tempPerm.append(el)
getPermutationList(elements, tempPerm, currList, checkReverse)
elements.insert(i, el)
tempPerm.pop()
if elements == []:
temp = copy(tempPerm)
# in tempPerm we have a permutation. Check if it already exists in the currList
for i in range(len(temp)):
el = temp.pop()
temp.insert(0, el)
if str(temp) in currList: return
if checkReverse == 1:
# also try the reverse permutation
temp.reverse()
for i in range(len(temp)):
el = temp.pop()
temp.insert(0, el)
if str(temp) in currList: return
currList[str(tempPerm)] = copy(tempPerm)
def fact(i):
ret = 1
while i > 1:
ret = ret*i
i -= 1
return ret
# return number of combinations where we select "select" from "total"
def combinations(select, total):
return fact(total)/ (fact(total-select)*fact(select))
SYMBOL = 0
PENCOLOR = 1
BRUSHCOLOR = 2
XANCHORS = 3
YANCHORS = 4
LINE_TOOLTIPS = 0
VISIBLE_ATTRIBUTES = 1
ALL_ATTRIBUTES = 2
TOOLTIPS_SHOW_DATA = 0
TOOLTIPS_SHOW_SPRINGS = 1
###########################################################################################
##### CLASS : OWPolyvizGRAPH
###########################################################################################
class OWPolyvizGraph(OWGraph, orngScalePolyvizData):
def __init__(self, polyvizWidget, parent = None, name = None):
"Constructs the graph"
OWGraph.__init__(self, parent, name)
orngScalePolyvizData.__init__(self)
self.lineLength = 2
self.totalPossibilities = 0 # a variable used in optimization - tells us the total number of different attribute positions
self.triedPossibilities = 0 # how many possibilities did we already try
self.startTime = time.time()
self.enhancedTooltips = 1
self.kNNOptimization = None
self.polyvizWidget = polyvizWidget
self.useDifferentSymbols = 0
self.useDifferentColors = 1
self.tooltipKind = 0 # index in ["Show line tooltips", "Show visible attributes", "Show all attributes"]
self.tooltipValue = 0 # index in ["Tooltips show data values", "Tooltips show spring values"]
self.dataMap = {} # each key is of form: "xVal-yVal", where xVal and yVal are discretized continuous values. Value of each key has form: (x,y, HSVValue, [data vals])
self.tooltipCurveKeys = []
self.tooltipMarkers = []
self.showLegend = 1
self.onlyOnePerSubset = 1
self.showProbabilities = 0
self.squareGranularity = 3
self.spaceBetweenCells = 1
# init axes
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.yLeft, -1.20, 1.20, 1)
def createAnchors(self, anchorNum):
anchors = [[],[]]
for i in range(anchorNum):
x = math.cos(2*math.pi * float(i) / float(anchorNum)); strX = "%.5f" % (x)
y = math.sin(2*math.pi * float(i) / float(anchorNum)); strY = "%.5f" % (y)
anchors[0].append(float(strX)) # this might look stupid, but this way we get rid of rounding errors
anchors[1].append(float(strY))
return anchors
def setData(self, data):
OWGraph.setData(self, data)
orngScalePolyvizData.setData(self, data)
#
# update shown data. Set labels, coloring by className ....
#
def updateData(self, labels, foo, **args):
#self.removeCurves()
self.removeDrawingCurves() # my function, that doesn't delete selection curves
self.removeMarkers()
self.tips.removeAll()
# initial var values
self.showKNNModel = 0
self.showCorrect = 1
self.__dict__.update(args)
length = len(labels)
self.dataMap = {} # dictionary with keys of form "x_i-y_i" with values (x_i, y_i, color, data)
self.XAnchor = self.createXAnchors(length)
self.YAnchor = self.createYAnchors(length)
self.shownAttributes = labels
polyvizLineCoordsX = []; polyvizLineCoordsY = [] # if class is discrete we will optimize drawing by storing computed values and adding less data curves to plot
# we must have at least 3 attributes to be able to show anything
if self.scaledData == None or len(labels) < 3:
self.updateLayout()
return
dataSize = len(self.rawdata)
classIsDiscrete = (self.rawdata.domain.classVar.varType == orange.VarTypes.Discrete)
classNameIndex = -1
self.setAxisScale(QwtPlot.xBottom, -1.20, 1.20 + 0.05 * self.showLegend, 1)
# store indices to shown attributes
indices = [self.attributeNameIndex[label] for label in labels]
if self.rawdata.domain.classVar.varType == orange.VarTypes.Discrete:
classValueIndices = getVariableValueIndices(self.rawdata, self.rawdata.domain.classVar.name)
classNameIndex = self.attributeNameIndex[self.rawdata.domain.classVar.name]
if self.rawdata.domain.classVar.varType == orange.VarTypes.Discrete: # if we have a discrete class
valLen = len(self.rawdata.domain.classVar.values)
classValueIndices = getVariableValueIndices(self.rawdata, self.rawdata.domain.classVar.name) # we create a hash table of variable values and their indices
else: # if we have a continuous class
valLen = 0
# will we show different symbols?
useDifferentSymbols = 0
if self.useDifferentSymbols and self.rawdata.domain.classVar.varType == orange.VarTypes.Discrete and valLen < len(self.curveSymbols): useDifferentSymbols = 1
dataSize = len(self.rawdata)
blackColor = QColor(0,0,0)
curveData = [[0, 0, 0, QwtSymbol.Ellipse, blackColor, blackColor, [], []] for i in range(dataSize)]
# ##########
# draw text at lines
for i in range(length):
# print attribute name
self.addMarker(labels[i], 0.6*(self.XAnchor[i]+ self.XAnchor[(i+1)%length]), 0.6*(self.YAnchor[i]+ self.YAnchor[(i+1)%length]), Qt.AlignHCenter + Qt.AlignVCenter, bold = 1)
if self.rawdata.domain[labels[i]].varType == orange.VarTypes.Discrete:
# print all possible attribute values
values = getVariableValuesSorted(self.rawdata, labels[i])
count = len(values)
k = 1.08
for j in range(count):
pos = (1.0 + 2.0*float(j)) / float(2*count)
self.addMarker(values[j], k*(1-pos)*self.XAnchor[i]+k*pos*self.XAnchor[(i+1)%length], k*(1-pos)*self.YAnchor[i]+k*pos*self.YAnchor[(i+1)%length], Qt.AlignHCenter + Qt.AlignVCenter)
else:
# min and max value
if self.tooltipValue == TOOLTIPS_SHOW_SPRINGS:
names = ["%.1f" % (0.0), "%.1f" % (1.0)]
elif self.tooltipValue == TOOLTIPS_SHOW_DATA:
names = ["%%.%df" % (self.rawdata.domain[labels[i]].numberOfDecimals) % (self.attrLocalValues[labels[i]][0]), "%%.%df" % (self.rawdata.domain[labels[i]].numberOfDecimals) % (self.attrLocalValues[labels[i]][1])]
self.addMarker(names[0],0.95*self.XAnchor[i]+0.15*self.XAnchor[(i+1)%length], 0.95*self.YAnchor[i]+0.15*self.YAnchor[(i+1)%length], Qt.AlignHCenter + Qt.AlignVCenter)
self.addMarker(names[1], 0.15*self.XAnchor[i]+0.95*self.XAnchor[(i+1)%length], 0.15*self.YAnchor[i]+0.95*self.YAnchor[(i+1)%length], Qt.AlignHCenter + Qt.AlignVCenter)
XAnchorPositions = Numeric.zeros([length, dataSize], Numeric.Float)
YAnchorPositions = Numeric.zeros([length, dataSize], Numeric.Float)
XAnchor = self.createXAnchors(length)
YAnchor = self.createYAnchors(length)
for i in range(length):
Xdata = XAnchor[i] * (1-self.noJitteringScaledData[indices[i]]) + XAnchor[(i+1)%length] * self.noJitteringScaledData[indices[i]]
Ydata = YAnchor[i] * (1-self.noJitteringScaledData[indices[i]]) + YAnchor[(i+1)%length] * self.noJitteringScaledData[indices[i]]
XAnchorPositions[i] = Xdata
YAnchorPositions[i] = Ydata
XAnchorPositions = Numeric.swapaxes(XAnchorPositions, 0,1)
YAnchorPositions = Numeric.swapaxes(YAnchorPositions, 0,1)
selectedData = Numeric.take(self.scaledData, indices)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -