📄 owhierarchicalclustering.py
字号:
"""
<name>Hierarchical Clustering</name>
<description>Hierarchical clustering based on distance matrix, and a dendrogram viewer.</description>
<icon>HierarchicalClustering.png</icon>
<contact>Ales Erjavec (ales.erjavec324(@at@)email.si)</contact>
<prority>1550</priority>
"""
from OWWidget import *
from qtcanvas import *
from sets import Set
import qt
import OWGUI
import OWGraphTools
import math
import os
try:
from OWDataFiles import DataFiles
except:
class DataFiles:
pass
class OWHierarchicalClustering(OWWidget):
settingsList=["Linkage", "OverwriteMatrix", "Annotation", "Brightness", "PrintDepthCheck",
"PrintDepth", "HDSize", "VDSize", "FitToWindow","AutoResize",
"TextSize", "LineSpacing", "ZeroOffset", "SelectionMode", "DisableHighlights",
"DisableBubble", "ClassifySelected", "CommitOnChange", "ClassifyName"]
def __init__(self, parent=None, signalManager=None):
#OWWidget.__init__(self, parent, 'Hierarchical Clustering')
OWWidget.__init__(self, parent, signalManager, 'Hierarchical Clustering')
self.parent=parent
self.callbackDeposit=[]
self.inputs=[("Distance matrix", orange.SymMatrix, self.dataset)]
self.outputs=[("Selected Examples", ExampleTable), ("Structured Data Files", DataFiles)]
self.linkage=[("Single ", orange.HierarchicalClustering.Single),
("Average", orange.HierarchicalClustering.Average),
("Complete", orange.HierarchicalClustering.Complete)]
self.Linkage=0
self.OverwriteMatrix=0
self.Annotation=0
self.Brightness=5
self.PrintDepthCheck=0
self.PrintDepth=100
self.HDSize=500 #initial horizontal and vertical dendogram size
self.VDSize=800
self.FitToWindow=0
self.AutoResize=0
self.TextSize=8
self.LineSpacing=4
self.SelectionMode=0
self.ZeroOffset=1
self.DisableHighlights=0
self.DisableBubble=0
self.ClassifySelected=0
self.CommitOnChange=0
self.ClassifyName="HC_class"
self.loadSettings()
self.AutoResize=False
self.inputMatrix=None
self.matrixSource="Unknown"
self.rootCluster=None
self.selectedExamples=None
self.ctrlPressed=FALSE
self.linkageMethods=[a[0] for a in self.linkage]
#################################
##GUI
#################################
#Tabs
self.tabs=QTabWidget(self.controlArea,"tabWidget")
self.settingsTab=QVGroupBox(self,"Settings")
self.selectionTab=QVGroupBox(self,"Selection")
self.tabs.insertTab(self.settingsTab, "Settings")
self.tabs.insertTab(self.selectionTab, "Selection")
#HC Settings
OWGUI.comboBox(self.settingsTab, self, "Linkage", box="Linkage",
items=self.linkageMethods, tooltip="Choose linkage method",
callback=self.constructTree)
#Label
self.labelCombo=OWGUI.comboBox(self.settingsTab, self, "Annotation",
box="Annotation", items=["None"],tooltip="Choose label attribute",
callback=self.updateLabel)
#Dendogram graphics settings
dendogramBox=QVGroupBox(self.settingsTab, "Dendogram")
dendogramBox.setTitle("Dendogram setings")
#OWGUI.spin(dendogramBox, self, "Brightness", label="Brigthtness",min=1,max=9,step=1)
OWGUI.checkWithSpin(dendogramBox, self, "Print depth", 1, 100, "PrintDepthCheck",
"PrintDepth")
#OWGUI.spin(dendogramBox, self, "VDSize", label="Vertical size", min=100,
# max=10000, step=10)
self.hSizeBox=OWGUI.spin(dendogramBox, self, "HDSize", label="Horizontal size", min=200,
max=10000, step=10)
OWGUI.checkBox(dendogramBox, self, "FitToWindow","Fit hor. size to window",
callback=lambda:self.hSizeBox.setDisabled(self.FitToWindow))
self.hSizeBox.setDisabled(self.FitToWindow)
#OWGUI.checkBox(dendogramBox, self, "FitToWindow", "Fit horizontal size")
#OWGUI.checkBox(dendogramBox, self, "AutoResize", "Auto resize")
OWGUI.spin(dendogramBox, self, "TextSize", label="Text font size",
min=5, max=15, step=1)
OWGUI.spin(dendogramBox,self, "LineSpacing", label="Line spacing",
min=2,max=8,step=1)
OWGUI.button(dendogramBox, self, "&Apply",self.applySettings)
#Selection options
OWGUI.checkBox(self.selectionTab, self, "SelectionMode", "Cutoff line",
callback=self.updateCutOffLine)
self.classificationBox=QVGroupBox(self.selectionTab)
#self.classificationBox.setTitle("Classification")
OWGUI.checkBox(self.classificationBox, self, "ClassifySelected","Classify selected examples")
OWGUI.lineEdit(self.classificationBox, self, "ClassifyName", "Class name")
#selectionBox=QVGroupBox(self.selectionTab)
commitBox=QVGroupBox(self.selectionTab)
commitBox.setTitle("Commit settings")
OWGUI.checkBox(commitBox, self, "CommitOnChange", "Commit on change")
OWGUI.button(commitBox, self, "&Commit", self.commitData)
OWGUI.checkBox(self.selectionTab, self, "DisableHighlights", "Disable highlights")
OWGUI.checkBox(self.selectionTab, self, "DisableBubble", "Disable bubble info")
OWGUI.button(self.controlArea, self, "&Save graph", self.saveGraph)
self.mainAreaLayout=QVBoxLayout(self.mainArea, QVBoxLayout.TopToBottom,0)
scale=QCanvas(self)
self.headerView=ScaleCanvas(self, scale, self.mainArea)
self.footerView=ScaleCanvas(self, scale, self.mainArea)
self.dendogram=Dendogram(self)
self.dendogramView=DendogramView(self.dendogram, self.mainArea)
self.mainAreaLayout.addWidget(self.headerView)
self.mainAreaLayout.addWidget(self.dendogramView)
self.mainAreaLayout.addWidget(self.footerView)
self.dendogram.header=self.headerView
self.dendogram.footer=self.footerView
self.connect(self.dendogramView.horizontalScrollBar(),SIGNAL("valueChanged(int)"),
self.footerView.horizontalScrollBar().setValue)
self.connect(self.dendogramView.horizontalScrollBar(),SIGNAL("valueChanged(int)"),
self.headerView.horizontalScrollBar().setValue)
self.dendogram.resize(self.HDSize,self.VDSize)
self.dendogram.update()
def dataset(self, data):
self.matrix=data
if not self.matrix:
self.rootCluster=None
self.selectedExamples=None
self.dendogram.clear()
self.footerView.clear()
self.labelCombo.clear()
self.send("Selected Examples", None)
self.classificationBox.setDisabled(True)
return
self.matrixSource="Unknown"
items=getattr(self.matrix, "items")
if type(items)==orange.ExampleTable: #Example Table from Example Distance
self.labels=["None","Default"]+ \
[a.name for a in items.domain.attributes]
if items.domain.classVar:
self.labels.append(items.domain.classVar.name)
self.labelInd=range(len(self.labels)-2)
self.labels.extend([m.name for m in items.domain.getmetas().values()])
self.labelInd.extend(items.domain.getmetas().keys())
#print self.labelInd
#print self.labels
self.numMeta=len(items.domain.getmetas())
self.metaLabels=items.domain.getmetas().values()
self.matrixSource="Example Distance"
elif type(items)==list: #Structured data files from Data Distance
self.labels=["None", "Default", "Name", "Strain"]
self.Annotation=0
self.matrixSource="Data Distance"
else: #From Attribute Distance
self.labels=["None","Attribute Name"]
self.Annotation=0
self.matrixSource="Attribute Distance"
self.labelCombo.clear()
for a in self.labels:
self.labelCombo.insertItem(a)
if self.labelCombo.count()<self.Annotation-1:
self.Annotation=0
self.labelCombo.setCurrentItem(self.Annotation)
if self.matrixSource=="Example Distance":
self.classificationBox.setDisabled(False)
else:
self.classificationBox.setDisabled(True)
self.constructTree()
def updateLabel(self):
items=self.matrix.items
if self.Annotation==0:
self.rootCluster.mapping.setattr("objects",
[" " for i in range(len(items))])
elif self.Annotation==1:
if self.matrixSource=="Example Distance" or self.matrixSource=="Data Distance":
self.rootCluster.mapping.setattr("objects", range(len(items)))
elif self.matrixSource=="Attribute Distance":
self.rootCluster.mapping.setattr("objects", [a.name for a in items])
elif self.matrixSource=="Example Distance":
try:
print self.labelInd[self.Annotation-2]
self.rootCluster.mapping.setattr("objects",
[str(e[self.labelInd[self.Annotation-2]]) for e in items])
except IndexError:
self.Annotation=0
self.rootCluster.mapping.setattr("objects", [str(e[0]) for e in items])
elif self.matrixSource=="Data Distance":
if self.Annotation==2:
self.rootCluster.mapping.setattr("objects", [getattr(a, "name", "") for a in items])
else:
self.rootCluster.mapping.setattr("objects", [getattr(a, "strain", "") for a in items])
#print self.rootCluster.mapping
self.dendogram.updateLabel()
def constructTree(self):
if self.matrix:
self.progressBarInit()
self.rootCluster=orange.HierarchicalClustering(self.matrix,
linkage=self.linkage[self.Linkage][1],
overwriteMatrix=self.OverwriteMatrix,
progressCallback=self.progressBarSet)
self.progressBarFinished()
self.dendogram.displayTree(self.rootCluster)
self.updateLabel()
def applySettings(self):
self.dendogram.resize(self.HDSize, self.VDSize)
self.dendogram.displayTree(self.rootCluster)
def progressBarSet(self, value, a):
OWWidget.progressBarSet(self, value*100)
def keyPressEvent(self, key):
if key.key()==Qt.Key_Control:
self.ctrlPressed=TRUE
else:
key.ignore()
def keyReleaseEvent(self, key):
if key.key()==Qt.Key_Control:
self.ctrlPressed=FALSE
else:
key.ignore()
def updateCutOffLine(self):
if self.SelectionMode:
self.dendogram.cutOffLine.show()
self.footerView.canvas().marker.show()
else:
self.dendogram.cutOffLine.hide()
self.footerView.canvas().marker.hide()
self.dendogram.update()
self.footerView.canvas().update()
def updateSelection(self, selection):
if self.matrixSource=="Attribute Distance":
return
self.selectionList=selection
if self.CommitOnChange and self.dendogram.cutOffLineDragged==False:
self.commitData()
def commitData(self):
self.selection=[]
selection=self.selectionList
maps=[self.rootCluster.mapping[c.first:c.last] for c in [e.rootCluster for e in selection]]
self.selection=[self.matrix.items[k] for k in [j for i in range(len(maps)) for j in maps[i]]]
if not self.selection:
self.send("Selected Examples",None)
self.send("Structured Data Files", None)
return
if self.matrixSource=="Example Distance":
if self.ClassifySelected:
classVar=orange.EnumVariable(self.ClassifyName ,
values=[str(i) for i in range(len(maps))])
domain=orange.Domain(self.matrix.items.domain.attributes,classVar)
if self.matrix.items.domain.classVar:
domain.addmetas(self.matrix.items.domain.getmetas())
id=orange.newmetaid()
domain.addmeta(id, self.matrix.items.domain.classVar)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -