📄 owmds.py
字号:
for i in range(self.mds.n):
for j in range(2):
self.mds.points[i][j] += st[j]*(random()-0.5)
if self.computeStress:
self.mds.getStress(self.stressFunc[self.StressFunc][1])
self.stress=self.getAvgStress(self.stressFunc[self.StressFunc][1])
self.graph.updateData()
def start(self):
if not getattr(self, "mds", None):
return
if self.done==False:
self.done=True
return
self.done=False
self.startButton.setText("Stop")
numIter=0
self.progressBarInit()
pcur=0
startStress=oldStress=stress=self.getAvgStress(self.stressFunc[self.StressFunc][1])
startTime=time.clock()
hist=[stress]*3
while not self.done and numIter<self.maxIterations:
for i in range(self.NumIter):
self.mds.SMACOFstep()
qApp.processEvents()
if self.computeStress:
self.mds.getStress(self.stressFunc[self.StressFunc][1])
self.stress=stress=self.getAvgStress(self.stressFunc[self.StressFunc][1])
hist.pop(0)
hist.append(abs(oldStress-stress))
numIter+=1
self.infoB.setText("Num. steps: %i" % numIter)
qApp.processEvents()
if self.ReDraw:
self.graph.updateData()
qApp.processEvents()
if self.computeStress and abs(sum(hist)/3)<abs(self.minStressDelta*oldStress):
break
## Update progress bar
p1=abs(self.minStressDelta*oldStress)/max(sum(hist)/3, 1e-6)*100
if p1>100: p1=0
pcur=min(max([p1, float(numIter)/self.maxIterations*100, pcur]),99)
self.progressBarSet(int(pcur))
oldStress=stress
self.startButton.setText("Start")
self.progressBarFinished()
#if not self.ReDraw:
self.graph.updateData()
self.done=True
#print "time %i " % (time.clock()-startTime)
def testStart(self):
if not getattr(self, "mds", None):
return
if self.done==False:
self.done=True
return
self.done=False
self.startButton.setText("Stop")
self.stopping.setDisabled(1)
self.progressBarInit()
self.iterNum=0
self.mds.progressCallback=self.callback
self.mds.mds.optimize(self.maxIterations, self.stressFunc[self.StressFunc][1], self.minStressDelta)
if self.iterNum%(math.pow(10,self.RefreshMode)):
self.graph.updateData()
self.startButton.setText("Start")
self.stopping.setDisabled(0)
self.progressBarFinished()
self.done=True
def callback(self, a,b=None):
if not self.iterNum%(math.pow(10,self.RefreshMode)):
self.graph.updateData()
self.iterNum+=1
self.infoB.setText("Num. steps: %i" % self.iterNum)
self.infoA.setText("Avg. Stress: %f" % self.mds.avgStress)
self.progressBarSet(int(a*100))
qApp.processEvents()
if self.done:
return 0
else:
return 1
def getAvgStress(self, stressf=orngMDS.SgnRelStress):
return self.mds.avgStress
"""
self.mds.getDistance()
total=0.0
total=sum([abs(a[0]) for a in self.mds.arr])
self.infoA.setText("Avg. stress: %.7f" % (total/(self.mds.n*self.mds.n)))
return total/(self.mds.n*self.mds.n)
"""
def sendSelections(self):
if not getattr(self, "mds", None):
return
selectedInd=[]
for i,(x,y) in enumerate(self.mds.points):
if self.graph.isPointSelected(x,y):
selectedInd+=[i]
if type(self.data)==orange.ExampleTable:
self.sendExampleTable(selectedInd)
elif type(self.data)==list:
self.sendList(selectedInd)
def sendExampleTable(self, selectedInd):
if self.selectionOptions==0:
self.send("Example Table", orange.ExampleTable(self.data.getitems(selectedInd)))
else:
xAttr=orange.FloatVariable("X")
yAttr=orange.FloatVariable("Y")
if self.selectionOptions==1:
domain=orange.Domain([xAttr, yAttr]+[v for v in self.data.domain.variables])
domain.addmetas(self.data.domain.getmetas())
else:
domain=orange.Domain(self.data.domain)
domain.addmeta(orange.newmetaid(), xAttr)
domain.addmeta(orange.newmetaid(), yAttr)
selection=orange.ExampleTable(domain)
selection.extend(self.data.getitems(selectedInd))
for i in range(len(selectedInd)):
selection[i][xAttr]=self.mds.points[selectedInd[i]][0]
selection[i][yAttr]=self.mds.points[selectedInd[i]][1]
self.send("Example Table", selection)
def sendList(self, selectedInd):
if not selectedInd:
self.send("Structured Data Files", None)
else:
datasets=[self.data[i] for i in selectedInd]
names=list(Set([d.dirname for d in datasets]))
data=[(name, [d for d in filter(lambda a:a.strain==name, datasets)]) for name in names]
self.send("Structured Data Files",data)
def updateStress(self):
if not getattr(self, "mds", None):
return
self.mds.getStress(self.stressFunc[self.StressFunc][1])
self.graph.setLines(True)
self.graph.replot()
class MDSGraph(OWGraph):
def __init__(self, parent=None, name=None):
OWGraph.__init__(self, parent, name)
self.data=None
self.mds=None
self.PointSize=5
self.ColorAttr=0
self.SizeAttr=0
self.ShapeAttr=0
self.NameAttr=0
self.ShowStress=False
self.NumStressLines=10
self.ShowName=True
self.curveKeys=[]
self.pointKeys=[]
self.points=[]
self.lines=[]
self.lineKeys=[]
self.colors=[]
self.sizes=[]
self.shapeList=[QwtSymbol.Ellipse,
QwtSymbol.Rect,
QwtSymbol.Diamond,
QwtSymbol.Triangle,
QwtSymbol.DTriangle ,
QwtSymbol.UTriangle,
QwtSymbol.LTriangle,
QwtSymbol.RTriangle,
QwtSymbol.Cross,
QwtSymbol.XCross ]
def setData(self, mds, colors, sizes, shapes, names):
if 1:
# if mds:
self.mds=mds
#self.data=data
self.colors=colors
self.sizes=sizes
self.shapes=shapes
self.names=names
self.updateData()
def updateData(self):
# if self.mds:
if 1:
self.clear()
self.setPoints()
if self.ShowStress:
self.setLines(True)
for axis in [QwtPlot.xBottom, QwtPlot.xTop, QwtPlot.yLeft, QwtPlot.yRight]:
self.setAxisAutoScale(axis)
self.updateAxes()
self.repaint()
def updateLines(self):
if self.mds:
self.setLines()
self.repaint()
def setPoints(self):
import sets
if self.ShapeAttr==0 and self.SizeAttr==0 and self.NameAttr==0:
colors=[c[self.ColorAttr] for c in self.colors]
set=[]
for c in colors:
if c not in set:
set.append(c)
#set=reduce(lambda set,a: (not(a in set)) and set.append(a), colors, [])
#set=sets.ImmutableSet([c[self.ColorAttr] for c in self.colors])
dict={}
for i in range(len(self.colors)):
c=self.colors[i][self.ColorAttr]
if dict.has_key(c.hsv()):
dict[c.hsv()].append(i)
else:
dict[c.hsv()]=[i]
for color in set:
#print len(dict[color.hsv()]), color.name()
X=[self.mds.points[i][0] for i in dict[color.hsv()]]
Y=[self.mds.points[i][1] for i in dict[color.hsv()]]
self.addCurve("A", color, color, self.PointSize, symbol=QwtSymbol.Ellipse, xData=X, yData=Y)
return
for i in range(len(self.colors)):
self.addCurve("a", self.colors[i][self.ColorAttr], self.colors[i][self.ColorAttr], self.sizes[i][self.SizeAttr]*1.0/5*self.PointSize,
symbol=self.shapes[i][self.ShapeAttr], xData=[self.mds.points[i][0]],yData=[self.mds.points[i][1]])
if self.NameAttr!=0:
self.addMarker(self.names[i][self.NameAttr], self.mds.points[i][0], self.mds.points[i][1], Qt.AlignRight)
def setLines(self, reset=False):
def removeCurve(keys):
self.removeCurve(keys[0])
if len(keys)==2:
self.removeCurve(keys[1])
if reset:
#for k in self.lineKeys:
# removeCurve(k)
self.lineKeys=[]
if not getattr(self, "mds", None): return
if self.NumStressLines<len(self.lineKeys):
for k in self.lineKeys[self.NumStressLines:]:
removeCurve(k)
self.lineKeys=self.lineKeys[:self.NumStressLines]
else:
#stress=[(abs(s),s,(a,b)) for s,(a,b) in self.mds.arr]
stress=[(abs(self.mds.stress[a,b]), self.mds.stress[a,b], (a,b))
for a in range(self.mds.n) for b in range(a)]
stress.sort()
stress.reverse()
for (as,s,(a,b)) in stress[len(self.lineKeys):min(self.NumStressLines, len(stress))]:
(xa,ya)=self.mds.points[a]
(xb,yb)=self.mds.points[b]
#color=s<0 and Qt.red or Qt.green
if self.mds.projectedDistances[a,b]-self.mds.distances[a,b]>0:
color=Qt.green
k1=self.addCurve("A", color, color, 0, QwtCurve.Lines, xData=[xa,xb], yData=[ya,yb], lineWidth=1)
r=self.mds.distances[a,b]/max(self.mds.projectedDistances[a,b], 1e-6)
xa1=xa+(1-r)/2*(xb-xa)
xb1=xb+(1-r)/2*(xa-xb)
ya1=ya+(1-r)/2*(yb-ya)
yb1=yb+(1-r)/2*(ya-yb)
k2=self.addCurve("A", color, color, 0, QwtCurve.Lines, xData=[xa1,xb1], yData=[ya1,yb1], lineWidth=4)
self.lineKeys.append( (k1,k2) )
else:
color=Qt.red
r=self.mds.distances[a,b]/max(self.mds.projectedDistances[a,b], 1e-6)
xa1=(xa+xb)/2+r/2*(xa-xb)
xb1=(xa+xb)/2+r/2*(xb-xa)
ya1=(ya+yb)/2+r/2*(ya-yb)
yb1=(ya+yb)/2+r/2*(yb-ya)
k1=self.addCurve("A", color, color, 0, QwtCurve.Lines, xData=[xa1,xb1], yData=[ya1,yb1], lineWidth=2)
self.lineKeys.append( (k1,) )
if __name__=="__main__":
app=QApplication(sys.argv)
w=OWMDS()
app.setMainWidget(w)
w.show()
data=orange.ExampleTable("../../doc/datasets/iris.tab")
#data=orange.ExampleTable("/home/ales/src/MDSjakulin/eu_nations.txt")
matrix = orange.SymMatrix(len(data))
dist = orange.ExamplesDistanceConstructor_Euclidean(data)
matrix = orange.SymMatrix(len(data))
matrix.setattr('items', data)
for i in range(len(data)):
for j in range(i+1):
matrix[i, j] = dist(data[i], data[j])
w.cmatrix(matrix)
app.exec_loop()
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -