📄 owlinproj.py
字号:
"""
<name>Linear Projection</name>
<description>Create a linear projection.</description>
<contact>Gregor Leban (gregor.leban@fri.uni-lj.si)</contact>
<icon>icons/LinearProjection.png</icon>
<priority>2000</priority>
"""
# LinProj.py
#
# Show a linear projection of the data
#
from OWVisWidget import *
from OWLinProjGraph import *
from OWkNNOptimization import OWVizRank
from OWClusterOptimization import *
from OWFreeVizOptimization import *
import OWToolbars, OWGUI, orngTest
import orngVisFuncts, OWDlgs
import orngVizRank
###########################################################################################
##### WIDGET : Linear Projection
###########################################################################################
class OWLinProj(OWVisWidget):
settingsList = ["graph.pointWidth", "graph.jitterSize", "graph.globalValueScaling", "graph.showFilledSymbols", "graph.scaleFactor",
"graph.showLegend", "graph.optimizedDrawing", "graph.useDifferentSymbols", "autoSendSelection", "graph.useDifferentColors",
"graph.tooltipKind", "graph.tooltipValue", "toolbarSelection", "graph.showClusters", "clusterClassifierName",
"showProbabilitiesDetails", "graph.showProbabilities", "graph.squareGranularity", "graph.spaceBetweenCells",
"valueScalingType", "showAllAttributes", "learnerIndex", "colorSettings", "addProjectedPositions", "VizRankLearnerName"]
jitterSizeNums = [0.0, 0.01, 0.1, 0.5, 1, 2, 3, 4, 5, 7, 10, 15, 20]
jitterSizeList = [str(x) for x in jitterSizeNums]
scaleFactorNums = [1.0, 1.1, 1.2, 1.3, 1.4, 1.5, 1.6, 1.7, 1.8, 1.9, 2.0, 2.2, 2.4, 2.6, 2.8, 3.0, 4.0, 5.0, 6.0, 8.0, 10.0, 15.0]
contextHandlers = {"": DomainContextHandler("", [ContextField("shownAttributes", DomainContextHandler.RequiredList, selected="selectedShown", reservoir="hiddenAttributes")])}
def __init__(self,parent=None, signalManager = None, name = "Linear Projection", graphClass = None):
OWWidget.__init__(self, parent, signalManager, name, TRUE)
self.inputs = [("Classified Examples", ExampleTableWithClass, self.cdata, Default), ("Example Subset", ExampleTable, self.subsetdata), ("Attribute Selection List", AttributeList, self.attributeSelection), ("Evaluation Results", orngTest.ExperimentResults, self.test_results), ("VizRank Learner", orange.Learner, self.vizRankLearner)]
self.outputs = [("Selected Examples", ExampleTableWithClass), ("Unselected Examples", ExampleTableWithClass), ("Attribute Selection List", AttributeList), ("Learner", orange.Learner)]
# local variables
self.learnersArray = [None, None, None, None] # VizRank, Cluster, FreeViz, S2N Heuristic Learner
self.showAllAttributes = 0
self.valueScalingType = 0
self.autoSendSelection = 1
self.data = None
self.toolbarSelection = 0
self.VizRankLearnerName = "VizRank (%s)" % name
self.clusterClassifierName = "Visual cluster classifier (Linear Projection)"
self.classificationResults = None
self.outlierValues = None
self.attributeSelectionList = None
self.learnerIndex = 0
self.colorSettings = None
self.addProjectedPositions = 0
self.showProbabilitiesDetails = 0
self.boxGeneral = 1
#add a graph widget
self.box = QVBoxLayout(self.mainArea)
if graphClass:
self.graph = graphClass(self, self.mainArea, name)
else:
self.graph = OWLinProjGraph(self, self.mainArea, name)
self.box.addWidget(self.graph)
# graph variables
self.graph.manualPositioning = 0
self.graph.hideRadius = 0
self.graph.showClusters = 0
self.graph.showAnchors = 1
self.graph.jitterContinuous = 0
self.graph.showProbabilities = 0
self.graph.optimizedDrawing = 1
self.graph.useDifferentSymbols = 0
self.graph.useDifferentColors = 1
self.graph.tooltipKind = 0
self.graph.tooltipValue = 0
self.graph.scaleFactor = 1.0
self.graph.showAxisScale = 0
# cluster dialog
self.clusterDlg = ClusterOptimization(self, self.signalManager, self.graph, name)
self.graph.clusterOptimization = self.clusterDlg
# freeviz dialog
self.freeVizDlg = FreeVizOptimization(self, self.signalManager, self.graph, name)
# optimization dialog
if name.lower() == "radviz":
self.vizrank = OWVizRank(self, self.signalManager, self.graph, orngVizRank.RADVIZ, name)
self.learnersArray[0] = VizRankLearner(RADVIZ, self.vizrank, self.graph)
self.connect(self.graphButton, SIGNAL("clicked()"), self.saveToFile)
elif name.lower() == "polyviz":
self.vizrank = OWVizRank(self, self.signalManager, self.graph, orngVizRank.POLYVIZ, name)
self.learnersArray[0] = VizRankLearner(POLYVIZ, self.vizrank, self.graph)
self.connect(self.graphButton, SIGNAL("clicked()"), self.graph.saveToFile)
else:
self.vizrank = OWVizRank(self, self.signalManager, self.graph, orngVizRank.LINEAR_PROJECTION, name)
self.learnersArray[0] = VizRankLearner(LINEAR_PROJECTION, self.vizrank, self.graph)
self.connect(self.graphButton, SIGNAL("clicked()"), self.saveToFile)
self.optimizationDlg = self.vizrank # for backward compatibility
self.learnersArray[2] = FreeVizLearner(self.freeVizDlg)
#load settings
self.loadSettings()
self.graph.normalizeExamples = (name.lower() == "radviz") # ignore settings!! if we have radviz then normalize, otherwise not.
#GUI
# add a settings dialog and initialize its values
self.tabs = QTabWidget(self.space, 'tabWidget')
self.GeneralTab = QVGroupBox(self)
#self.GeneralTab.setFrameShape(QFrame.NoFrame)
self.SettingsTab = QVGroupBox(self)
self.tabs.insertTab(self.GeneralTab, "General")
self.tabs.insertTab(self.SettingsTab, "Settings")
#add controls to self.controlArea widget
self.createShowHiddenLists(self.GeneralTab, callback = self.updateGraphAndAnchors)
self.optimizationButtons = OWGUI.widgetBox(self.GeneralTab, " Optimization Dialogs ", orientation = "horizontal")
self.vizrankButton = OWGUI.button(self.optimizationButtons, self, "VizRank", callback = self.vizrank.reshow, tooltip = "Opens VizRank dialog, where you can search for interesting projections with different subsets of attributes.", debuggingEnabled = 0)
self.clusterDetectionDlgButton = OWGUI.button(self.optimizationButtons, self, "Cluster", callback = self.clusterDlg.reshow, debuggingEnabled = 0)
self.freeVizDlgButton = OWGUI.button(self.optimizationButtons, self, "FreeViz", callback = self.freeVizDlg.reshow, tooltip = "Opens FreeViz dialog, where the position of attribute anchors is optimized so that class separation is improved", debuggingEnabled = 0)
self.vizrankButton.setMaximumWidth(63)
self.clusterDetectionDlgButton.setMaximumWidth(63)
self.freeVizDlgButton.setMaximumWidth(63)
self.connect(self.clusterDlg.startOptimizationButton , SIGNAL("clicked()"), self.optimizeClusters)
self.connect(self.clusterDlg.resultList, SIGNAL("selectionChanged()"),self.showSelectedCluster)
self.zoomSelectToolbar = OWToolbars.ZoomSelectToolbar(self, self.GeneralTab, self.graph, self.autoSendSelection)
self.graph.autoSendSelectionCallback = self.selectionChanged
self.connect(self.zoomSelectToolbar.buttonSendSelections, SIGNAL("clicked()"), self.sendSelections)
# ####################################
# SETTINGS TAB
# #####
self.extraTopBox = OWGUI.widgetBox(self.SettingsTab, orientation = "vertical")
self.extraTopBox.hide()
OWGUI.hSlider(self.SettingsTab, self, 'graph.pointWidth', box=' Point Size ', minValue=1, maxValue=15, step=1, callback = self.updateGraph)
box = OWGUI.widgetBox(self.SettingsTab, " Jittering Options ")
OWGUI.comboBoxWithCaption(box, self, "graph.jitterSize", 'Jittering size (% of size) ', callback = self.resetGraphData, items = self.jitterSizeNums, sendSelectedValue = 1, valueType = float)
OWGUI.checkBox(box, self, 'graph.jitterContinuous', 'Jitter continuous attributes', callback = self.resetGraphData, tooltip = "Does jittering apply also on continuous attributes?")
box2a = OWGUI.widgetBox(self.SettingsTab, " Scaling Options ")
OWGUI.comboBoxWithCaption(box2a, self, "graph.scaleFactor", 'Scale point position by: ', callback = self.updateGraph, items = self.scaleFactorNums, sendSelectedValue = 1, valueType = float)
valueScalingList = ["attribute range", "global range", "attribute variance"]
if name.lower() in ["radviz", "polyviz"]:
valueScalingList.pop(); self.valueScalingType = min(self.valueScalingType, 1)
OWGUI.comboBoxWithCaption(box2a, self, "valueScalingType", 'Scale values by: ', callback = self.setValueScaling, items = valueScalingList)
box3 = OWGUI.collapsableWidgetBox(self.SettingsTab, " General Graph Settings ", self, "boxGeneral")
#OWGUI.checkBox(box3, self, 'graph.normalizeExamples', 'Normalize examples', callback = self.updateGraph)
OWGUI.checkBox(box3, self, 'graph.showLegend', 'Show legend', callback = self.updateGraph)
OWGUI.checkBox(box3, self, 'graph.optimizedDrawing', 'Optimize drawing', callback = self.updateGraph, tooltip = "Speed up drawing by drawing all point belonging to one class value at once")
OWGUI.checkBox(box3, self, 'graph.useDifferentSymbols', 'Use different symbols', callback = self.updateGraph, tooltip = "Show different class values using different symbols")
OWGUI.checkBox(box3, self, 'graph.useDifferentColors', 'Use different colors', callback = self.updateGraph, tooltip = "Show different class values using different colors")
OWGUI.checkBox(box3, self, 'graph.showFilledSymbols', 'Show filled symbols', callback = self.updateGraph)
OWGUI.checkBox(box3, self, 'graph.showClusters', 'Show clusters', callback = self.updateGraph, tooltip = "Show a line boundary around a significant cluster")
box5 = OWGUI.widgetBox(box3, orientation = "horizontal")
OWGUI.checkBox(box5, self, 'graph.showProbabilities', 'Show probabilities ', callback = self.updateGraph, tooltip = "Show a background image with class probabilities")
hider = OWGUI.widgetHider(box5, self, "showProbabilitiesDetails", tooltip = "Show/hide extra settings")
rubb = OWGUI.rubber(box5)
rubb.setSizePolicy(QSizePolicy(QSizePolicy.MinimumExpanding, QSizePolicy.Maximum))
box6 = OWGUI.widgetBox(box3, orientation = "horizontal")
OWGUI.label(box6, self, " Granularity: ")
OWGUI.hSlider(box6, self, 'graph.squareGranularity', minValue=1, maxValue=10, step=1, callback = self.updateGraph)
box7 = OWGUI.widgetBox(box3, orientation = "horizontal")
OWGUI.separator(box7, 17)
OWGUI.checkBox(box7, self, 'graph.spaceBetweenCells', 'Show space between cells', callback = self.updateGraph)
hider.setWidgets([box6, box7])
# ####
hbox = OWGUI.widgetBox(self.SettingsTab, "Colors", orientation = "horizontal")
OWGUI.button(hbox, self, "Set Colors", self.setColors, tooltip = "Set the canvas background color and color palette for coloring continuous variables", debuggingEnabled = 0)
box2 = OWGUI.widgetBox(self.SettingsTab, " Tooltips Settings ")
OWGUI.comboBox(box2, self, "graph.tooltipKind", items = ["Show line tooltips", "Show visible attributes", "Show all attributes"], callback = self.updateGraph)
OWGUI.comboBox(box2, self, "graph.tooltipValue", items = ["Tooltips show data values", "Tooltips show spring values"], callback = self.updateGraph, tooltip = "Do you wish that tooltips would show you original values of visualized attributes or the 'spring' values (values between 0 and 1). \nSpring values are scaled values that are used for determining the position of shown points. Observing these values will therefore enable you to \nunderstand why the points are placed where they are.")
box4 = OWGUI.widgetBox(self.SettingsTab, " Sending Selection ")
OWGUI.checkBox(box4, self, 'autoSendSelection', 'Auto send selected/unselected data', callback = self.selectionChanged, tooltip = "Send signals with selected data whenever the selection changes.")
OWGUI.comboBox(box4, self, "addProjectedPositions", items = ["Do not modify the domain", "Append projection as attributes", "Append projection as meta attributes"], callback = self.sendSelections)
self.selectionChanged()
self.activeLearnerCombo = OWGUI.comboBox(self.SettingsTab, self, "learnerIndex", box = " Set Active Learner ", items = ["VizRank Learner", "Cluster Learner", "FreeViz Learner", "S2N Feature Selection Learner"], tooltip = "Select which of the possible learners do you want to send on the widget output.", callback = self.setActiveLearner)
self.icons = self.createAttributeIconDict()
self.debugSettings = ["hiddenAttributes", "shownAttributes"]
# add a settings dialog and initialize its values
self.activateLoadedSettings()
self.setValueScaling() # XXX is there any better way to do this?!
self.resize(900, 700)
self.grid.activate()
self.SettingsTab.updateGeometry()
def saveToFile(self):
self.graph.saveToFile([("Save PixTex", self.graph.savePicTeX)])
def activateLoadedSettings(self):
dlg = self.createColorDialog()
self.graph.contPalette = dlg.getContinuousPalette("contPalette")
self.graph.discPalette = dlg.getDiscretePalette()
self.graph.setCanvasBackground(dlg.getColor("Canvas"))
apply([self.zoomSelectToolbar.actionZooming, self.zoomSelectToolbar.actionRectangleSelection, self.zoomSelectToolbar.actionPolygonSelection][self.toolbarSelection], [])
self.clusterDlg.changeLearnerName(self.clusterClassifierName)
self.cbShowAllAttributes()
self.setActiveLearner()
self.setValueScaling()
# #########################
# KNN OPTIMIZATION BUTTON EVENTS
# #########################
def saveCurrentProjection(self):
qname = QFileDialog.getSaveFileName( os.path.realpath(".") + "/Linear_projection.tab", "Orange Example Table (*.tab)", self, "", "Save File")
if qname.isEmpty(): return
name = str(qname)
if len(name) < 4 or name[-4] != ".":
name = name + ".tab"
self.graph.saveProjectionAsTabData(name, self.getShownAttributeList())
# ################################################################################################
# find projections that have tight clusters of points that belong to the same class value
def optimizeClusters(self):
if self.data == None: return
if not self.hasDiscreteClass(self.data):
QMessageBox.critical( None, "Cluster Detection Dialog", 'Clusters can be detected only in data sets with a discrete class value', QMessageBox.Ok)
return
self.clusterDlg.clearResults()
self.clusterDlg.clusterStabilityButton.setOn(0)
self.clusterDlg.pointStability = None
try:
listOfAttributes = self.vizrank.getEvaluatedAttributes(self.data)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -