Пример #1
0
 def __init__(self, parent=None, signalManager=None, name="Model Map"):
     OWNxExplorer.__init__(self, parent, signalManager, name, 
                            NetworkCanvas=OWModelMapCanvas)
     
     self.inputs = [("Distances", orange.SymMatrix, self.setMatrix, Default),
                    ("Model Subset", orange.ExampleTable, self.setSubsetModels)]
     self.outputs = [("Model", orange.Example),
                     ("Classifier", orange.Classifier),
                     ("Selected Models", orange.ExampleTable)]
     
     self.vertexSize = 32
     self.autoSendSelection = False
     self.minVertexSize = 16
     self.maxVertexSize = 16
     self.lastColorAttribute = ""
     self.lastSizeAttribute = ""
     self.vizAccurancy = False
     self.vizAttributes = False
     self.radius = 100
     self.attrIntersection = []
     self.attrIntersectionList = []
     self.attrDifference = []
     self.attrDifferenceList = []
     
     self.loadSettings()
     
     self.matrixTab = OWGUI.widgetBox(self.tabs, addToLayout = 0, margin = 4)
     self.modelTab = OWGUI.widgetBox(self.tabs, addToLayout = 0, margin = 4)
     self.tabs.insertTab(0, self.matrixTab, "Matrix")
     self.tabs.insertTab(1, self.modelTab, "Model Info")
     self.tabs.setCurrentIndex(self.tabIndex)
     
     self.networkCanvas.appendToSelection = 0
     self.networkCanvas.minVertexSize = self.minVertexSize
     self.networkCanvas.maxVertexSize = self.maxVertexSize
     self.networkCanvas.invertEdgeSize = 1
     
     # MARTIX CONTROLS
     self.addHistogramControls(self.matrixTab)
     self.kNN = 1
     boxHistogram = OWGUI.widgetBox(self.matrixTab, box = "Distance histogram")
     self.histogram = OWHist(self, boxHistogram)
     boxHistogram.layout().addWidget(self.histogram)
     
     # VISUALIZATION CONTROLS
     vizPredAcc = OWGUI.widgetBox(self.modelTab, "Prediction Accuracy", orientation = "vertical")
     OWGUI.checkBox(vizPredAcc, self, "vizAccurancy", "Visualize prediction accurancy", callback=self.visualizeInfo)
     OWGUI.spin(vizPredAcc, self, "radius", 10, 300, 1, label="Radius: ", callback = self.visualizeInfo)
     self.predGraph = OWDistributionGraph(self, vizPredAcc)
     self.predGraph.setMaximumSize(QSize(300, 300))
     self.predGraph.setYRlabels(None)
     self.predGraph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0, 0.1)
     self.predGraph.numberOfBars = 2
     self.predGraph.barSize = 200 / (self.predGraph.numberOfBars + 1)
     vizPredAcc.layout().addWidget(self.predGraph)
     
     vizPredAcc = OWGUI.widgetBox(self.modelTab, "Attribute lists", orientation = "vertical")
     OWGUI.checkBox(vizPredAcc, self, "vizAttributes", "Display attribute lists", callback = self.visualizeInfo)
     self.attrIntersectionBox = OWGUI.listBox(vizPredAcc, self, "attrIntersection", "attrIntersectionList", "Attribute intersection", selectionMode=QListWidget.NoSelection)
     self.attrDifferenceBox = OWGUI.listBox(vizPredAcc, self, "attrDifference", "attrDifferenceList", "Attribute difference", selectionMode=QListWidget.NoSelection)
     
     self.attBox.hide()
     self.visualizeInfo()
     
     QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.node_selection_changed)
     
     self.matrixTab.layout().addStretch(1)
     self.modelTab.layout().addStretch(1)
Пример #2
0
    def __init__(self, parent=None, signalManager=None, name="Model Map"):
        OWNxExplorer.__init__(self,
                              parent,
                              signalManager,
                              name,
                              NetworkCanvas=OWModelMapCanvas)

        self.inputs = [
            ("Distances", orange.SymMatrix, self.setMatrix, Default),
            ("Model Subset", orange.ExampleTable, self.setSubsetModels)
        ]
        self.outputs = [("Model", orange.Example),
                        ("Classifier", orange.Classifier),
                        ("Selected Models", orange.ExampleTable)]

        self.vertexSize = 32
        self.autoSendSelection = False
        self.minVertexSize = 16
        self.maxVertexSize = 16
        self.lastColorAttribute = ""
        self.lastSizeAttribute = ""
        self.vizAccurancy = False
        self.vizAttributes = False
        self.radius = 100
        self.attrIntersection = []
        self.attrIntersectionList = []
        self.attrDifference = []
        self.attrDifferenceList = []

        self.loadSettings()

        self.matrixTab = OWGUI.widgetBox(self.tabs, addToLayout=0, margin=4)
        self.modelTab = OWGUI.widgetBox(self.tabs, addToLayout=0, margin=4)
        self.tabs.insertTab(0, self.matrixTab, "Matrix")
        self.tabs.insertTab(1, self.modelTab, "Model Info")
        self.tabs.setCurrentIndex(self.tabIndex)

        self.networkCanvas.appendToSelection = 0
        self.networkCanvas.minVertexSize = self.minVertexSize
        self.networkCanvas.maxVertexSize = self.maxVertexSize
        self.networkCanvas.invertEdgeSize = 1

        # MARTIX CONTROLS
        self.addHistogramControls(self.matrixTab)
        self.kNN = 1
        boxHistogram = OWGUI.widgetBox(self.matrixTab,
                                       box="Distance histogram")
        self.histogram = OWHist(self, boxHistogram)
        boxHistogram.layout().addWidget(self.histogram)

        # VISUALIZATION CONTROLS
        vizPredAcc = OWGUI.widgetBox(self.modelTab,
                                     "Prediction Accuracy",
                                     orientation="vertical")
        OWGUI.checkBox(vizPredAcc,
                       self,
                       "vizAccurancy",
                       "Visualize prediction accurancy",
                       callback=self.visualizeInfo)
        OWGUI.spin(vizPredAcc,
                   self,
                   "radius",
                   10,
                   300,
                   1,
                   label="Radius: ",
                   callback=self.visualizeInfo)
        self.predGraph = OWDistributionGraph(self, vizPredAcc)
        self.predGraph.setMaximumSize(QSize(300, 300))
        self.predGraph.setYRlabels(None)
        self.predGraph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0, 0.1)
        self.predGraph.numberOfBars = 2
        self.predGraph.barSize = 200 / (self.predGraph.numberOfBars + 1)
        vizPredAcc.layout().addWidget(self.predGraph)

        vizPredAcc = OWGUI.widgetBox(self.modelTab,
                                     "Attribute lists",
                                     orientation="vertical")
        OWGUI.checkBox(vizPredAcc,
                       self,
                       "vizAttributes",
                       "Display attribute lists",
                       callback=self.visualizeInfo)
        self.attrIntersectionBox = OWGUI.listBox(
            vizPredAcc,
            self,
            "attrIntersection",
            "attrIntersectionList",
            "Attribute intersection",
            selectionMode=QListWidget.NoSelection)
        self.attrDifferenceBox = OWGUI.listBox(
            vizPredAcc,
            self,
            "attrDifference",
            "attrDifferenceList",
            "Attribute difference",
            selectionMode=QListWidget.NoSelection)

        self.attBox.hide()
        self.visualizeInfo()

        QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'),
                        self.node_selection_changed)

        self.matrixTab.layout().addStretch(1)
        self.modelTab.layout().addStretch(1)
Пример #3
0
class OWModelMapQt(OWNxExplorer, OWNxHist):
#    settingsList = ["vertexSize", "lastSizeAttribute", "lastColorAttribute", 
#                    "maxVertexSize", "minVertexSize", "tabIndex", 
#                    "colorSettings", "selectedSchemaIndex", "iterations", 
#                    "radius", "vizAccurancy", "vizAttributes", 
#                    "autoSendSelection", "spinExplicit", "spinPercentage",
#                    "maxLinkSize", "renderAntialiased", "labelsOnMarkedOnly",
#                    "invertSize", "optMethod", "lastVertexSizeColumn", 
#                    "lastColorColumn", "lastNameComponentAttribute", 
#                    "lastLabelColumns", "lastTooltipColumns", "showWeights",
#                    "showIndexes",  "showEdgeLabels", "edgeColorSettings", 
#                    "selectedEdgeSchemaIndex", "showMissingValues", "fontSize", 
#                    "mdsTorgerson", "mdsAvgLinkage", "mdsSteps", "mdsRefresh", 
#                    "mdsStressDelta", "organism","showTextMiningInfo", 
#                    "toolbarSelection", "minComponentEdgeWidth", 
#                    "maxComponentEdgeWidth", "mdsFromCurrentPos"]
#    
    settingsList = ["autoSendSelection", "spinExplicit", "spinPercentage",
        "maxLinkSize", "minVertexSize", "maxVertexSize", "networkCanvas.animate_plot",
        "networkCanvas.animate_points", "networkCanvas.antialias_plot", 
        "networkCanvas.antialias_points", "networkCanvas.antialias_lines", 
        "networkCanvas.auto_adjust_performance", "invertSize", "optMethod", 
        "lastVertexSizeColumn", "lastColorColumn", "networkCanvas.show_indices", "networkCanvas.show_weights",
        "lastNameComponentAttribute", "lastLabelColumns", "lastTooltipColumns",
        "showWeights", "showEdgeLabels", "colorSettings", 
        "selectedSchemaIndex", "edgeColorSettings", "selectedEdgeSchemaIndex",
        "showMissingValues", "fontSize", "mdsTorgerson", "mdsAvgLinkage",
        "mdsSteps", "mdsRefresh", "mdsStressDelta", "organism","showTextMiningInfo", 
        "toolbarSelection", "minComponentEdgeWidth", "maxComponentEdgeWidth",
        "mdsFromCurrentPos", "labelsOnMarkedOnly", "tabIndex", 
        "networkCanvas.trim_label_words", "opt_from_curr", "networkCanvas.explore_distances",
        "networkCanvas.show_component_distances", "fontWeight", "networkCanvas.state",
        "networkCanvas.selection_behavior"] 
    
    def __init__(self, parent=None, signalManager=None, name="Model Map"):
        OWNxExplorer.__init__(self, parent, signalManager, name, 
                               NetworkCanvas=OWModelMapCanvas)
        
        self.inputs = [("Distances", orange.SymMatrix, self.setMatrix, Default),
                       ("Model Subset", orange.ExampleTable, self.setSubsetModels)]
        self.outputs = [("Model", orange.Example),
                        ("Classifier", orange.Classifier),
                        ("Selected Models", orange.ExampleTable)]
        
        self.vertexSize = 32
        self.autoSendSelection = False
        self.minVertexSize = 16
        self.maxVertexSize = 16
        self.lastColorAttribute = ""
        self.lastSizeAttribute = ""
        self.vizAccurancy = False
        self.vizAttributes = False
        self.radius = 100
        self.attrIntersection = []
        self.attrIntersectionList = []
        self.attrDifference = []
        self.attrDifferenceList = []
        
        self.loadSettings()
        
        self.matrixTab = OWGUI.widgetBox(self.tabs, addToLayout = 0, margin = 4)
        self.modelTab = OWGUI.widgetBox(self.tabs, addToLayout = 0, margin = 4)
        self.tabs.insertTab(0, self.matrixTab, "Matrix")
        self.tabs.insertTab(1, self.modelTab, "Model Info")
        self.tabs.setCurrentIndex(self.tabIndex)
        
        self.networkCanvas.appendToSelection = 0
        self.networkCanvas.minVertexSize = self.minVertexSize
        self.networkCanvas.maxVertexSize = self.maxVertexSize
        self.networkCanvas.invertEdgeSize = 1
        
        # MARTIX CONTROLS
        self.addHistogramControls(self.matrixTab)
        self.kNN = 1
        boxHistogram = OWGUI.widgetBox(self.matrixTab, box = "Distance histogram")
        self.histogram = OWHist(self, boxHistogram)
        boxHistogram.layout().addWidget(self.histogram)
        
        # VISUALIZATION CONTROLS
        vizPredAcc = OWGUI.widgetBox(self.modelTab, "Prediction Accuracy", orientation = "vertical")
        OWGUI.checkBox(vizPredAcc, self, "vizAccurancy", "Visualize prediction accurancy", callback=self.visualizeInfo)
        OWGUI.spin(vizPredAcc, self, "radius", 10, 300, 1, label="Radius: ", callback = self.visualizeInfo)
        self.predGraph = OWDistributionGraph(self, vizPredAcc)
        self.predGraph.setMaximumSize(QSize(300, 300))
        self.predGraph.setYRlabels(None)
        self.predGraph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0, 0.1)
        self.predGraph.numberOfBars = 2
        self.predGraph.barSize = 200 / (self.predGraph.numberOfBars + 1)
        vizPredAcc.layout().addWidget(self.predGraph)
        
        vizPredAcc = OWGUI.widgetBox(self.modelTab, "Attribute lists", orientation = "vertical")
        OWGUI.checkBox(vizPredAcc, self, "vizAttributes", "Display attribute lists", callback = self.visualizeInfo)
        self.attrIntersectionBox = OWGUI.listBox(vizPredAcc, self, "attrIntersection", "attrIntersectionList", "Attribute intersection", selectionMode=QListWidget.NoSelection)
        self.attrDifferenceBox = OWGUI.listBox(vizPredAcc, self, "attrDifference", "attrDifferenceList", "Attribute difference", selectionMode=QListWidget.NoSelection)
        
        self.attBox.hide()
        self.visualizeInfo()
        
        QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.node_selection_changed)
        
        self.matrixTab.layout().addStretch(1)
        self.modelTab.layout().addStretch(1)
        
    def plotAccuracy(self, vertices=None):
        self.predGraph.tips.removeAll()
        self.predGraph.clear()
        #self.predGraph.setAxisScale(QwtPlot.yRight, 0.0, 1.0, 0.2)
        self.predGraph.setAxisScale(QwtPlot.xBottom,  0.0, 1.0, 0.2)
        
        if not vertices:
            self.predGraph.replot()
            return
        
        self.predGraph.setAxisScale(QwtPlot.yLeft, -0.5, len(self.matrix.originalData.domain.classVar.values) - 0.5, 1)
        
        scores = [[float(ca) for ca in ex["CA by class"].value.split(", ")] for ex in self.graph.items().getitems(vertices)]
        scores = [sum(score) / len(score) for score in zip(*scores)]
        
        currentBarsHeight = [0] * len(scores)
        for cn, score in enumerate(scores):
            subBarHeight = score
            ckey = PolygonCurve(pen = QPen(self.predGraph.discPalette[cn]), brush = QBrush(self.predGraph.discPalette[cn]))
            ckey.attach(self.predGraph)
            ckey.setRenderHint(QwtPlotItem.RenderAntialiased, self.predGraph.useAntialiasing)
        
            tmpx = cn - (self.predGraph.barSize/2.0)/100.0
            tmpx2 = cn + (self.predGraph.barSize/2.0)/100.0
            ckey.setData([currentBarsHeight[cn], currentBarsHeight[cn] + subBarHeight, currentBarsHeight[cn] + subBarHeight, currentBarsHeight[cn]], [tmpx, tmpx, tmpx2, tmpx2])
            currentBarsHeight[cn] += subBarHeight
            
        self.predGraph.replot()
        
    def displayAttributeInfo(self, vertices=None):
        self.attrIntersectionList = []
        self.attrDifferenceList = []
        
        if vertices is None or len(vertices) == 0:
            return
        
        attrList = [self.graph.items()[v]["attributes"].value.split(", ") for v in vertices]
        
        attrIntersection = set(attrList[0])
        attrUnion = set()
        for attrs in attrList:
            attrIntersection = attrIntersection.intersection(attrs)
            attrUnion = attrUnion.union(attrs)
            
        self.attrIntersectionList = attrIntersection
        self.attrDifferenceList = attrUnion.difference(attrIntersection)
            
    def visualizeInfo(self):
        self.networkCanvas.radius = self.radius
        
        if self.vizAccurancy:
            self.networkCanvas.plotAccuracy = self.plotAccuracy
        else:
            self.networkCanvas.plotAccuracy = None
            self.plotAccuracy(None)
            
        if self.vizAttributes:
            self.networkCanvas.vizAttributes = self.displayAttributeInfo
        else:
            self.networkCanvas.vizAttributes = None
            self.displayAttributeInfo(None)
            
    def setSubsetModels(self, subsetData):
        self.info()
        
        if "uuid" not in subsetData.domain:
            self.info("Invalid subset data. Data domain must contain 'uuid' attribute.")
            return
        
        uuids = set([ex["uuid"].value for ex in subsetData])
        for v in self.vertices:
            v.highlight = 1 if v.uuid in uuids else 0
                
    def setMatrix(self, matrix):
        self.warning()
        
        if matrix is None:
            self.warning("Data matrix is None.")
            return
        
        if not hasattr(matrix, "items") or not hasattr(matrix, "results") or not hasattr(matrix, "originalData"):
            self.warning("Data matrix does not have required data for items, results and originalData.")
            return
        
        requiredAttrs = set(["CA", "AUC", "attributes", "uuid"])
        attrs = [attr.name for attr in matrix.items.domain] 
        if len(requiredAttrs.intersection(attrs)) != len(requiredAttrs):
            self.warning("Items ExampleTable does not contain required attributes: %s." % ", ".join(requiredAttrs))
            return
            
        for ex in matrix.items:
            ex["attributes"] = ", ".join(sorted(ex["attributes"].value.split(", ")))
            
        OWNxHist.setMatrix(self, matrix)
        
    def set_node_sizes(self):
        OWNxExplorer.set_node_sizes(self)
        self.networkCanvas.loadIcons()
        self.networkCanvas.replot()
        
    def set_node_styles(self):
        #for v in self.networkCanvas.networkCurve.nodes().itervalues():
        #    #auc = self.graph.items()[v.index()]
        #    v.style = 1 #auc
        pass            
        
    def node_selection_changed(self):
        self.warning()
        
        if self.graph is None or self.graph.items() is None or self.graph_matrix is None:
            self.send("Model", None)
            self.send("Selected Models", None)
            return
        
        if self.graph.number_of_nodes() != self.graph_matrix.dim:
            self.warning('Network items and matrix results not of equal length.')
            self.send("Model", None)
            self.send("Selected Models", None)
            return
                    
        selection = self.networkCanvas.selected_nodes()
        
        if len(selection) == 1:
            modelInstance = self.graph.items()[selection[0]]
            # modelInfo - Python Dict; keys: method, classifier, probabilities,
            # results, XAnchors, YAnchors, attributes
            modelInfo = self.graph_matrix.results[modelInstance['uuid'].value]
            
            #uuid = modelInstance["uuid"].value
            #method, vizr_result, projection_points, classifier, attrs = self.matrix.results[uuid]
            
            if 'YAnchors' in modelInfo and 'XAnchors' in modelInfo:
                if not modelInstance.domain.hasmeta('anchors'):
                    modelInstance.domain.addmeta(orange.newmetaid(), orange.PythonVariable('anchors'))
                modelInstance['anchors'] = (modelInfo['XAnchors'], modelInfo['YAnchors'])
                
            if 'classifier' in modelInfo and modelInfo['classifier'] is not None:
                if not modelInstance.domain.hasmeta('classifier'):
                    modelInstance.domain.addmeta(orange.newmetaid(), orange.PythonVariable('classifier'))
                modelInstance['classifier'] = modelInfo['classifier']
                self.send('Classifier', modelInfo['classifier'])
                
            self.send('Model', modelInstance)
            self.send('Selected Models', self.graph.items().getitems(selection))
        elif len(selection) > 1: 
            self.send('Model', None)
            self.send('Selected Models', self.graph.items().getitems(selection))
        else:
            self.send('Model', None)
            self.send('Selected Models', None)
            
    def setColors(self):
        dlg = self.createColorDialog(self.colorSettings, self.selectedSchemaIndex)
        if dlg.exec_():
            self.colorSettings = dlg.getColorSchemas()
            self.selectedSchemaIndex = dlg.selectedSchemaIndex
            self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
            self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
            
            self.set_node_colors()
            
    def set_node_colors(self):
        if self.graph is None:
            return
        
        self.networkCanvas.set_node_colors(self.colorCombo.currentText())
        self.lastColorAttribute = self.colorCombo.currentText()
        #self.networkCanvas.updateData()
        #self.networkCanvas.replot()
            
    def sendSignals(self):
        if self.graph is None or self.graph_matrix is None:
            return
        
        self.set_graph(self.graph, ModelCurve)
        self.set_items_distance_matrix(self.graph_matrix)
        # TODO clickedAttLstBox -> setLabelText(["attributes"]
        
        nodes = self.networkCanvas.networkCurve.nodes()
        for i, ex in enumerate(self.graph.items()):
            nodes[i].uuid = ex["uuid"].value
        
        self.set_node_sizes()
        self.set_node_styles()
        self.set_node_colors()
        
        labels = self.matrix.originalData.domain.classVar.values.native()
        self.predGraph.numberOfBars = len(labels)
        self.predGraph.barSize = 200 / (self.predGraph.numberOfBars + 1)
        self.predGraph.setYLlabels(labels)
        #self.predGraph.setShowMainTitle(self.showMainTitle)
        #self.predGraph.setYLaxisTitle(self.matrix.originalData.domain.classVar.name)
        #self.predGraph.setShowYLaxisTitle(True)
        self.predGraph.setAxisScale(QwtPlot.xBottom,  0.0, 1.0, 0.2)
        self.predGraph.setAxisScale(QwtPlot.yLeft, -0.5, len(self.matrix.originalData.domain.classVar.values) - 0.5, 1)
    
        self.predGraph.enableYRaxis(0)
        self.predGraph.setYRaxisTitle("")
        self.predGraph.setXaxisTitle("CA")
        self.predGraph.setShowXaxisTitle(True)
        self.predGraph.replot()
        
        self.visualizeInfo()
Пример #4
0
class OWModelMapQt(OWNxExplorer, OWNxHist):
    #    settingsList = ["vertexSize", "lastSizeAttribute", "lastColorAttribute",
    #                    "maxVertexSize", "minVertexSize", "tabIndex",
    #                    "colorSettings", "selectedSchemaIndex", "iterations",
    #                    "radius", "vizAccurancy", "vizAttributes",
    #                    "autoSendSelection", "spinExplicit", "spinPercentage",
    #                    "maxLinkSize", "renderAntialiased", "labelsOnMarkedOnly",
    #                    "invertSize", "optMethod", "lastVertexSizeColumn",
    #                    "lastColorColumn", "lastNameComponentAttribute",
    #                    "lastLabelColumns", "lastTooltipColumns", "showWeights",
    #                    "showIndexes",  "showEdgeLabels", "edgeColorSettings",
    #                    "selectedEdgeSchemaIndex", "showMissingValues", "fontSize",
    #                    "mdsTorgerson", "mdsAvgLinkage", "mdsSteps", "mdsRefresh",
    #                    "mdsStressDelta", "organism","showTextMiningInfo",
    #                    "toolbarSelection", "minComponentEdgeWidth",
    #                    "maxComponentEdgeWidth", "mdsFromCurrentPos"]
    #
    settingsList = [
        "autoSendSelection", "spinExplicit", "spinPercentage", "maxLinkSize",
        "minVertexSize", "maxVertexSize", "networkCanvas.animate_plot",
        "networkCanvas.animate_points", "networkCanvas.antialias_plot",
        "networkCanvas.antialias_points", "networkCanvas.antialias_lines",
        "networkCanvas.auto_adjust_performance", "invertSize", "optMethod",
        "lastVertexSizeColumn", "lastColorColumn",
        "networkCanvas.show_indices", "networkCanvas.show_weights",
        "lastNameComponentAttribute", "lastLabelColumns", "lastTooltipColumns",
        "showWeights", "showEdgeLabels", "colorSettings",
        "selectedSchemaIndex", "edgeColorSettings", "selectedEdgeSchemaIndex",
        "showMissingValues", "fontSize", "mdsTorgerson", "mdsAvgLinkage",
        "mdsSteps", "mdsRefresh", "mdsStressDelta", "organism",
        "showTextMiningInfo", "toolbarSelection", "minComponentEdgeWidth",
        "maxComponentEdgeWidth", "mdsFromCurrentPos", "labelsOnMarkedOnly",
        "tabIndex", "networkCanvas.trim_label_words", "opt_from_curr",
        "networkCanvas.explore_distances",
        "networkCanvas.show_component_distances", "fontWeight",
        "networkCanvas.state", "networkCanvas.selection_behavior"
    ]

    def __init__(self, parent=None, signalManager=None, name="Model Map"):
        OWNxExplorer.__init__(self,
                              parent,
                              signalManager,
                              name,
                              NetworkCanvas=OWModelMapCanvas)

        self.inputs = [
            ("Distances", orange.SymMatrix, self.setMatrix, Default),
            ("Model Subset", orange.ExampleTable, self.setSubsetModels)
        ]
        self.outputs = [("Model", orange.Example),
                        ("Classifier", orange.Classifier),
                        ("Selected Models", orange.ExampleTable)]

        self.vertexSize = 32
        self.autoSendSelection = False
        self.minVertexSize = 16
        self.maxVertexSize = 16
        self.lastColorAttribute = ""
        self.lastSizeAttribute = ""
        self.vizAccurancy = False
        self.vizAttributes = False
        self.radius = 100
        self.attrIntersection = []
        self.attrIntersectionList = []
        self.attrDifference = []
        self.attrDifferenceList = []

        self.loadSettings()

        self.matrixTab = OWGUI.widgetBox(self.tabs, addToLayout=0, margin=4)
        self.modelTab = OWGUI.widgetBox(self.tabs, addToLayout=0, margin=4)
        self.tabs.insertTab(0, self.matrixTab, "Matrix")
        self.tabs.insertTab(1, self.modelTab, "Model Info")
        self.tabs.setCurrentIndex(self.tabIndex)

        self.networkCanvas.appendToSelection = 0
        self.networkCanvas.minVertexSize = self.minVertexSize
        self.networkCanvas.maxVertexSize = self.maxVertexSize
        self.networkCanvas.invertEdgeSize = 1

        # MARTIX CONTROLS
        self.addHistogramControls(self.matrixTab)
        self.kNN = 1
        boxHistogram = OWGUI.widgetBox(self.matrixTab,
                                       box="Distance histogram")
        self.histogram = OWHist(self, boxHistogram)
        boxHistogram.layout().addWidget(self.histogram)

        # VISUALIZATION CONTROLS
        vizPredAcc = OWGUI.widgetBox(self.modelTab,
                                     "Prediction Accuracy",
                                     orientation="vertical")
        OWGUI.checkBox(vizPredAcc,
                       self,
                       "vizAccurancy",
                       "Visualize prediction accurancy",
                       callback=self.visualizeInfo)
        OWGUI.spin(vizPredAcc,
                   self,
                   "radius",
                   10,
                   300,
                   1,
                   label="Radius: ",
                   callback=self.visualizeInfo)
        self.predGraph = OWDistributionGraph(self, vizPredAcc)
        self.predGraph.setMaximumSize(QSize(300, 300))
        self.predGraph.setYRlabels(None)
        self.predGraph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0, 0.1)
        self.predGraph.numberOfBars = 2
        self.predGraph.barSize = 200 / (self.predGraph.numberOfBars + 1)
        vizPredAcc.layout().addWidget(self.predGraph)

        vizPredAcc = OWGUI.widgetBox(self.modelTab,
                                     "Attribute lists",
                                     orientation="vertical")
        OWGUI.checkBox(vizPredAcc,
                       self,
                       "vizAttributes",
                       "Display attribute lists",
                       callback=self.visualizeInfo)
        self.attrIntersectionBox = OWGUI.listBox(
            vizPredAcc,
            self,
            "attrIntersection",
            "attrIntersectionList",
            "Attribute intersection",
            selectionMode=QListWidget.NoSelection)
        self.attrDifferenceBox = OWGUI.listBox(
            vizPredAcc,
            self,
            "attrDifference",
            "attrDifferenceList",
            "Attribute difference",
            selectionMode=QListWidget.NoSelection)

        self.attBox.hide()
        self.visualizeInfo()

        QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'),
                        self.node_selection_changed)

        self.matrixTab.layout().addStretch(1)
        self.modelTab.layout().addStretch(1)

    def plotAccuracy(self, vertices=None):
        self.predGraph.tips.removeAll()
        self.predGraph.clear()
        #self.predGraph.setAxisScale(QwtPlot.yRight, 0.0, 1.0, 0.2)
        self.predGraph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0, 0.2)

        if not vertices:
            self.predGraph.replot()
            return

        self.predGraph.setAxisScale(
            QwtPlot.yLeft, -0.5,
            len(self.matrix.originalData.domain.classVar.values) - 0.5, 1)

        scores = [[float(ca) for ca in ex["CA by class"].value.split(", ")]
                  for ex in self.graph.items().getitems(vertices)]
        scores = [sum(score) / len(score) for score in zip(*scores)]

        currentBarsHeight = [0] * len(scores)
        for cn, score in enumerate(scores):
            subBarHeight = score
            ckey = PolygonCurve(pen=QPen(self.predGraph.discPalette[cn]),
                                brush=QBrush(self.predGraph.discPalette[cn]))
            ckey.attach(self.predGraph)
            ckey.setRenderHint(QwtPlotItem.RenderAntialiased,
                               self.predGraph.useAntialiasing)

            tmpx = cn - (self.predGraph.barSize / 2.0) / 100.0
            tmpx2 = cn + (self.predGraph.barSize / 2.0) / 100.0
            ckey.setData([
                currentBarsHeight[cn], currentBarsHeight[cn] + subBarHeight,
                currentBarsHeight[cn] + subBarHeight, currentBarsHeight[cn]
            ], [tmpx, tmpx, tmpx2, tmpx2])
            currentBarsHeight[cn] += subBarHeight

        self.predGraph.replot()

    def displayAttributeInfo(self, vertices=None):
        self.attrIntersectionList = []
        self.attrDifferenceList = []

        if vertices is None or len(vertices) == 0:
            return

        attrList = [
            self.graph.items()[v]["attributes"].value.split(", ")
            for v in vertices
        ]

        attrIntersection = set(attrList[0])
        attrUnion = set()
        for attrs in attrList:
            attrIntersection = attrIntersection.intersection(attrs)
            attrUnion = attrUnion.union(attrs)

        self.attrIntersectionList = attrIntersection
        self.attrDifferenceList = attrUnion.difference(attrIntersection)

    def visualizeInfo(self):
        self.networkCanvas.radius = self.radius

        if self.vizAccurancy:
            self.networkCanvas.plotAccuracy = self.plotAccuracy
        else:
            self.networkCanvas.plotAccuracy = None
            self.plotAccuracy(None)

        if self.vizAttributes:
            self.networkCanvas.vizAttributes = self.displayAttributeInfo
        else:
            self.networkCanvas.vizAttributes = None
            self.displayAttributeInfo(None)

    def setSubsetModels(self, subsetData):
        self.info()

        if "uuid" not in subsetData.domain:
            self.info(
                "Invalid subset data. Data domain must contain 'uuid' attribute."
            )
            return

        uuids = set([ex["uuid"].value for ex in subsetData])
        for v in self.vertices:
            v.highlight = 1 if v.uuid in uuids else 0

    def setMatrix(self, matrix):
        self.warning()

        if matrix is None:
            self.warning("Data matrix is None.")
            return

        if not hasattr(matrix, "items") or not hasattr(
                matrix, "results") or not hasattr(matrix, "originalData"):
            self.warning(
                "Data matrix does not have required data for items, results and originalData."
            )
            return

        requiredAttrs = set(["CA", "AUC", "attributes", "uuid"])
        attrs = [attr.name for attr in matrix.items.domain]
        if len(requiredAttrs.intersection(attrs)) != len(requiredAttrs):
            self.warning(
                "Items ExampleTable does not contain required attributes: %s."
                % ", ".join(requiredAttrs))
            return

        for ex in matrix.items:
            ex["attributes"] = ", ".join(
                sorted(ex["attributes"].value.split(", ")))

        OWNxHist.setMatrix(self, matrix)

    def set_node_sizes(self):
        OWNxExplorer.set_node_sizes(self)
        self.networkCanvas.loadIcons()
        self.networkCanvas.replot()

    def set_node_styles(self):
        #for v in self.networkCanvas.networkCurve.nodes().itervalues():
        #    #auc = self.graph.items()[v.index()]
        #    v.style = 1 #auc
        pass

    def node_selection_changed(self):
        self.warning()

        if self.graph is None or self.graph.items(
        ) is None or self.graph_matrix is None:
            self.send("Model", None)
            self.send("Selected Models", None)
            return

        if self.graph.number_of_nodes() != self.graph_matrix.dim:
            self.warning(
                'Network items and matrix results not of equal length.')
            self.send("Model", None)
            self.send("Selected Models", None)
            return

        selection = self.networkCanvas.selected_nodes()

        if len(selection) == 1:
            modelInstance = self.graph.items()[selection[0]]
            # modelInfo - Python Dict; keys: method, classifier, probabilities,
            # results, XAnchors, YAnchors, attributes
            modelInfo = self.graph_matrix.results[modelInstance['uuid'].value]

            #uuid = modelInstance["uuid"].value
            #method, vizr_result, projection_points, classifier, attrs = self.matrix.results[uuid]

            if 'YAnchors' in modelInfo and 'XAnchors' in modelInfo:
                if not modelInstance.domain.hasmeta('anchors'):
                    modelInstance.domain.addmeta(
                        orange.newmetaid(), orange.PythonVariable('anchors'))
                modelInstance['anchors'] = (modelInfo['XAnchors'],
                                            modelInfo['YAnchors'])

            if 'classifier' in modelInfo and modelInfo[
                    'classifier'] is not None:
                if not modelInstance.domain.hasmeta('classifier'):
                    modelInstance.domain.addmeta(
                        orange.newmetaid(),
                        orange.PythonVariable('classifier'))
                modelInstance['classifier'] = modelInfo['classifier']
                self.send('Classifier', modelInfo['classifier'])

            self.send('Model', modelInstance)
            self.send('Selected Models',
                      self.graph.items().getitems(selection))
        elif len(selection) > 1:
            self.send('Model', None)
            self.send('Selected Models',
                      self.graph.items().getitems(selection))
        else:
            self.send('Model', None)
            self.send('Selected Models', None)

    def setColors(self):
        dlg = self.createColorDialog(self.colorSettings,
                                     self.selectedSchemaIndex)
        if dlg.exec_():
            self.colorSettings = dlg.getColorSchemas()
            self.selectedSchemaIndex = dlg.selectedSchemaIndex
            self.networkCanvas.contPalette = dlg.getContinuousPalette(
                "contPalette")
            self.networkCanvas.discPalette = dlg.getDiscretePalette(
                "discPalette")

            self.set_node_colors()

    def set_node_colors(self):
        if self.graph is None:
            return

        self.networkCanvas.set_node_colors(self.colorCombo.currentText())
        self.lastColorAttribute = self.colorCombo.currentText()
        #self.networkCanvas.updateData()
        #self.networkCanvas.replot()

    def sendSignals(self):
        if self.graph is None or self.graph_matrix is None:
            return

        self.set_graph(self.graph, ModelCurve)
        self.set_items_distance_matrix(self.graph_matrix)
        # TODO clickedAttLstBox -> setLabelText(["attributes"]

        nodes = self.networkCanvas.networkCurve.nodes()
        for i, ex in enumerate(self.graph.items()):
            nodes[i].uuid = ex["uuid"].value

        self.set_node_sizes()
        self.set_node_styles()
        self.set_node_colors()

        labels = self.matrix.originalData.domain.classVar.values.native()
        self.predGraph.numberOfBars = len(labels)
        self.predGraph.barSize = 200 / (self.predGraph.numberOfBars + 1)
        self.predGraph.setYLlabels(labels)
        #self.predGraph.setShowMainTitle(self.showMainTitle)
        #self.predGraph.setYLaxisTitle(self.matrix.originalData.domain.classVar.name)
        #self.predGraph.setShowYLaxisTitle(True)
        self.predGraph.setAxisScale(QwtPlot.xBottom, 0.0, 1.0, 0.2)
        self.predGraph.setAxisScale(
            QwtPlot.yLeft, -0.5,
            len(self.matrix.originalData.domain.classVar.values) - 0.5, 1)

        self.predGraph.enableYRaxis(0)
        self.predGraph.setYRaxisTitle("")
        self.predGraph.setXaxisTitle("CA")
        self.predGraph.setShowXaxisTitle(True)
        self.predGraph.replot()

        self.visualizeInfo()