source: orange/orange/OrangeWidgets/Visualize Qt/OWNxExplorerQt.py @ 9546:2b6cc6f397fe

Revision 9546:2b6cc6f397fe, 69.1 KB checked in by ales_erjavec <ales.erjavec@…>, 2 years ago (diff)

Renamed widget channel names in line with the new naming rules/convention.
Added backwards compatibility in orngDoc loadDocument to enable loading of schemas saved before the change.

Line 
1"""
2THIS WIDGET IS NOW INCLUDED IN OWNxExplorer.py
3"""
4import math
5import operator
6import statc
7import time
8
9import Orange 
10import OWGUI
11import OWColorPalette
12import OWToolbars
13import orngMDS
14
15from OWWidget import *
16from OWNxCanvasQt import *
17from operator import itemgetter
18
19dir = os.path.dirname(__file__) + "/../icons/"
20dlg_mark2sel = dir + "Dlg_Mark2Sel.png"
21dlg_sel2mark = dir + "Dlg_Sel2Mark.png"
22dlg_selIsmark = dir + "Dlg_SelisMark.png"
23dlg_selected = dir + "Dlg_SelectedNodes.png"
24dlg_unselected = dir + "Dlg_UnselectedNodes.png"
25dlg_showall = dir + "Dlg_clear.png"
26
27class OWNxExplorerQt(OWWidget):
28    settingsList = ["autoSendSelection", "spinExplicit", "spinPercentage",
29    "maxLinkSize", "minVertexSize", "maxVertexSize", "networkCanvas.animate_plot",
30    "networkCanvas.animate_points", "networkCanvas.antialias_plot", 
31    "networkCanvas.antialias_points", "networkCanvas.antialias_lines", 
32    "networkCanvas.auto_adjust_performance", "invertSize", "optMethod", 
33    "lastVertexSizeColumn", "lastColorColumn", "networkCanvas.show_indices", "networkCanvas.show_weights",
34    "lastNameComponentAttribute", "lastLabelColumns", "lastTooltipColumns",
35    "showWeights", "showEdgeLabels", "colorSettings", 
36    "selectedSchemaIndex", "edgeColorSettings", "selectedEdgeSchemaIndex",
37    "showMissingValues", "fontSize", "mdsTorgerson", "mdsAvgLinkage",
38    "mdsSteps", "mdsRefresh", "mdsStressDelta", "organism","showTextMiningInfo", 
39    "toolbarSelection", "minComponentEdgeWidth", "maxComponentEdgeWidth",
40    "mdsFromCurrentPos", "labelsOnMarkedOnly", "tabIndex", 
41    "networkCanvas.trim_label_words", "opt_from_curr", "networkCanvas.explore_distances",
42    "networkCanvas.show_component_distances"] 
43   
44    def __init__(self, parent=None, signalManager=None, name = 'Net Explorer (qt)', 
45                 NetworkCanvas=OWNxCanvas):
46        OWWidget.__init__(self, parent, signalManager, name)
47        #self.contextHandlers = {"": DomainContextHandler("", [ContextField("attributes", selected="markerAttributes"), ContextField("attributes", selected="tooltipAttributes"), "color"])}
48        self.inputs = [("Nx View", Orange.network.NxView, self.set_network_view),
49                       ("Network", Orange.network.Graph, self.set_graph, Default),
50                       ("Items", Orange.data.Table, self.setItems),
51                       ("Marked Itenms", Orange.data.Table, self.markItems), 
52                       ("Item Subset", Orange.data.Table, self.setExampleSubset), 
53                       ("Distances", Orange.core.SymMatrix, self.set_items_distance_matrix)]
54       
55        self.outputs = [("Selected Network", Orange.network.Graph),
56                        ("Distance Matrix", Orange.core.SymMatrix),
57                        ("Selected Items", Orange.data.Table), 
58                        ("Other Items", Orange.data.Table), 
59                        ("Marked Items", Orange.data.Table),
60                        ("Features", AttributeList)]
61       
62        self.networkCanvas = NetworkCanvas(self, self.mainArea, "Net Explorer")
63       
64        self.markerAttributes = []
65        self.tooltipAttributes = []
66        self.edgeLabelAttributes = []
67        self.attributes = []
68        self.edgeAttributes = []
69        self.autoSendSelection = False
70        self.graphShowGrid = 1  # show gridlines in the graph
71       
72        self.markNConnections = 2
73        self.markNumber = 0
74        self.markProportion = 0
75        self.markSearchString = ""
76        self.markDistance = 2
77        self.frSteps = 1
78        self.hubs = 0
79        self.color = 0
80        self.edgeColor = 0
81        self.vertexSize = 0
82        self.nShown = self.nHidden = self.nMarked = self.nSelected = self.verticesPerEdge = self.edgesPerVertex = self.diameter = self.clustering_coefficient = 0
83        self.optimizeWhat = 1
84        self.maxLinkSize = 3
85        self.maxVertexSize = 5
86        self.minVertexSize = 5
87        self.labelsOnMarkedOnly = 0
88        self.invertSize = 0
89        self.optMethod = 0
90        self.lastVertexSizeColumn = ''
91        self.lastColorColumn = ''
92        self.lastNameComponentAttribute = ''
93        self.lastLabelColumns = set()
94        self.lastTooltipColumns = set()
95        self.showWeights = 0
96        self.showEdgeLabels = 0
97        self.colorSettings = None
98        self.selectedSchemaIndex = 0
99        self.edgeColorSettings = [('net_edges', [[], [('contPalette', (4294967295L, 4278190080L, 0))], [('discPalette', [(204, 204, 204), (179, 226, 205), (253, 205, 172), (203, 213, 232), (244, 202, 228), (230, 245, 201), (255, 242, 174), (241, 226, 204)])]]), ('Default', [[], [('contPalette', (4294967295L, 4278190080L, 0))], [('discPalette', [(0, 0, 255), (255, 0, 0), (0, 255, 0), (255, 128, 0), (255, 255, 0), (255, 0, 255), (0, 255, 255), (128, 0, 255), (0, 128, 255), (255, 223, 128), (127, 111, 64), (92, 46, 0), (0, 84, 0), (192, 192, 0), (0, 127, 127), (128, 0, 0), (127, 0, 127)])]])]
100        self.selectedEdgeSchemaIndex = 0
101        self.items_matrix = None
102        self.showDistances = 0
103        self.showMissingValues = 0
104        self.fontSize = 12
105        self.mdsTorgerson = 0
106        self.mdsAvgLinkage = 1
107        self.mdsSteps = 10000
108        self.mdsRefresh = 50
109        self.mdsStressDelta = 0.0000001
110        self.organism = 'goa_human'
111        self.showTextMiningInfo = 0
112        self.toolbarSelection = 0
113        self.minComponentEdgeWidth = 10
114        self.maxComponentEdgeWidth = 70
115        self.mdsFromCurrentPos = 0
116        self.tabIndex = 0
117        self.number_of_nodes_label = -1
118        self.number_of_edges_label = -1
119        self.opt_from_curr = False
120       
121        self.loadSettings()
122       
123        self._network_view = None
124        self.graph = None
125        self.graph_base = None
126        self.markInputItems = None
127       
128        # if optimization method is set to FragViz, set it to FR
129        if self.optMethod == 9:
130            self.optMethod = 3
131       
132        self.mainArea.layout().setContentsMargins(0,4,4,4)
133        self.controlArea.layout().setContentsMargins(4,4,0,4)
134       
135        self.networkCanvas.showMissingValues = self.showMissingValues
136        self.mainArea.layout().addWidget(self.networkCanvas)
137       
138        self.networkCanvas.maxLinkSize = self.maxLinkSize
139       
140        self.hcontroArea = OWGUI.widgetBox(self.controlArea, orientation='horizontal')
141       
142        self.tabs = OWGUI.tabWidget(self.hcontroArea)
143       
144        self.verticesTab = OWGUI.createTabPage(self.tabs, "Nodes")
145        self.edgesTab = OWGUI.createTabPage(self.tabs, "Edges")
146        self.markTab = OWGUI.createTabPage(self.tabs, "Mark")
147        self.infoTab = OWGUI.createTabPage(self.tabs, "Info")
148        self.performanceTab = OWGUI.createTabPage(self.tabs, "Performance")
149       
150        self.tabs.setCurrentIndex(self.tabIndex)
151        self.connect(self.tabs, SIGNAL("currentChanged(int)"), lambda index: setattr(self, 'tabIndex', index))
152       
153        self.optimizeBox = OWGUI.radioButtonsInBox(self.verticesTab, self, "optimizeWhat", [], "Optimize", addSpace=False)
154       
155        self.optCombo = OWGUI.comboBox(self.optimizeBox, self, "optMethod", label='Method:     ', orientation='horizontal', callback=self.graph_layout_method)
156        self.optCombo.addItem("No optimization")
157        self.optCombo.addItem("Random")
158        self.optCombo.addItem("Fruchterman Reingold")
159        self.optCombo.addItem("Fruchterman Reingold Weighted")
160        self.optCombo.addItem("Fruchterman Reingold Radial")
161        self.optCombo.addItem("Circular Crossing Reduction")
162        self.optCombo.addItem("Circular Original")
163        self.optCombo.addItem("Circular Random")
164        self.optCombo.addItem("Pivot MDS")
165        self.optCombo.addItem("FragViz")
166        self.optCombo.addItem("MDS")
167        self.optCombo.setCurrentIndex(self.optMethod)
168        self.stepsSpin = OWGUI.spin(self.optimizeBox, self, "frSteps", 1, 100000, 1, label="Iterations: ")
169        self.cb_opt_from_curr = OWGUI.checkBox(self.optimizeBox, self, "opt_from_curr", label="Optimize from current positions")
170        self.cb_opt_from_curr.setEnabled(False)
171        self.stepsSpin.setEnabled(False)
172       
173        self.optButton = OWGUI.button(self.optimizeBox, self, "Optimize layout", callback=self.graph_layout, toggleButton=1)
174       
175        colorBox = OWGUI.widgetBox(self.verticesTab, "Node color attribute", orientation="horizontal", addSpace = False)
176        self.colorCombo = OWGUI.comboBox(colorBox, self, "color", callback=self.set_node_colors)
177        self.colorCombo.addItem("(same color)")
178        OWGUI.button(colorBox, self, "Set node color palette", self.setColors, tooltip = "Set node color palette", debuggingEnabled = 0)
179       
180        ib = OWGUI.widgetBox(self.verticesTab, "Node size attribute", orientation="vertical", addSpace = False)
181        hb = OWGUI.widgetBox(ib, orientation="horizontal", addSpace = False)
182        OWGUI.checkBox(hb, self, "invertSize", "Invert size", callback = self.set_node_sizes)
183        OWGUI.spin(hb, self, "minVertexSize", 5, 200, 1, label="Min:", callback=self.set_node_sizes)
184        OWGUI.spin(hb, self, "maxVertexSize", 5, 200, 1, label="Max:", callback=self.set_node_sizes)
185        self.vertexSizeCombo = OWGUI.comboBox(ib, self, "vertexSize", callback=self.set_node_sizes)
186        self.vertexSizeCombo.addItem("(none)")
187       
188        self.attBox = OWGUI.widgetBox(self.verticesTab, "Node labels | tooltips", orientation="vertical", addSpace = False)
189        OWGUI.spin(self.attBox, self, "fontSize", 4, 30, 1, label="Set font size:", callback = self.set_font_size)
190        hb = OWGUI.widgetBox(self.attBox, orientation="horizontal", addSpace = False)
191        self.attListBox = OWGUI.listBox(hb, self, "markerAttributes", "attributes", selectionMode=QListWidget.MultiSelection, callback=self.clickedAttLstBox)
192        self.tooltipListBox = OWGUI.listBox(hb, self, "tooltipAttributes", "attributes", selectionMode=QListWidget.MultiSelection, callback=self.clickedTooltipLstBox)       
193        OWGUI.spin(self.attBox, self, "networkCanvas.trim_label_words", 0, 5, 1, label='Trim label words to', callback=self.clickedAttLstBox)
194       
195        ib = OWGUI.widgetBox(self.edgesTab, "General", orientation="vertical")
196        OWGUI.checkBox(ib, self, 'networkCanvas.show_weights', 'Show weights', callback=self.networkCanvas.set_edge_labels)
197        #OWGUI.checkBox(ib, self, 'showEdgeLabels', 'Show labels on edges', callback=(lambda: self._set_canvas_attr('showEdgeLabels', self.showEdgeLabels)))
198        OWGUI.spin(ib, self, "maxLinkSize", 1, 50, 1, label="Max edge width:", callback = self.set_edge_sizes)
199        self.cb_show_distances = OWGUI.checkBox(ib, self, 'networkCanvas.explore_distances', 'Explore node distances', callback=None, disabled=1)
200        self.cb_show_component_distances = OWGUI.checkBox(ib, self, 'networkCanvas.show_component_distances', 'Show component distances', callback=self.networkCanvas.set_show_component_distances, disabled=1)
201       
202        colorBox = OWGUI.widgetBox(self.edgesTab, "Edge color attribute", orientation="horizontal", addSpace = False)
203        self.edgeColorCombo = OWGUI.comboBox(colorBox, self, "edgeColor", callback=self.set_edge_colors)
204        self.edgeColorCombo.addItem("(same color)")
205        OWGUI.button(colorBox, self, "Set edge color palette", self.setEdgeColorPalette, tooltip = "Set edge color palette", debuggingEnabled = 0)
206       
207        self.edgeLabelBox = OWGUI.widgetBox(self.edgesTab, "Edge labels", addSpace = False)
208        self.edgeLabelListBox = OWGUI.listBox(self.edgeLabelBox, self, "edgeLabelAttributes", "edgeAttributes", selectionMode=QListWidget.MultiSelection, callback=self.clickedEdgeLabelListBox)
209        #self.edgeLabelBox.setEnabled(False)
210       
211        ib = OWGUI.widgetBox(self.verticesTab, "General", orientation="vertical")
212        OWGUI.checkBox(ib, self, 'networkCanvas.show_indices', 'Show indices', callback=self.networkCanvas.set_node_labels)
213        OWGUI.checkBox(ib, self, 'labelsOnMarkedOnly', 'Show labels on marked nodes only', callback=(lambda: self.networkCanvas.set_labels_on_marked_only(self.labelsOnMarkedOnly)))
214       
215        ib = OWGUI.widgetBox(self.markTab, "Info", orientation="vertical")
216        OWGUI.label(ib, self, "Nodes (shown/hidden): %(number_of_nodes_label)i (%(nShown)i/%(nHidden)i)")
217        OWGUI.label(ib, self, "Selected: %(nSelected)i, marked: %(nMarked)i")
218       
219        ribg = OWGUI.radioButtonsInBox(self.markTab, self, "hubs", [], "Mark", callback = self.set_mark_mode)
220        OWGUI.appendRadioButton(ribg, self, "hubs", "None", callback = self.set_mark_mode)
221        OWGUI.appendRadioButton(ribg, self, "hubs", "Search", callback = self.set_mark_mode)
222        self.ctrlMarkSearchString = OWGUI.lineEdit(OWGUI.indentedBox(ribg), self, "markSearchString", callback=self.setSearchStringTimer, callbackOnType=True)
223        self.searchStringTimer = QTimer(self)
224        self.connect(self.searchStringTimer, SIGNAL("timeout()"), self.set_mark_mode)
225       
226        OWGUI.appendRadioButton(ribg, self, "hubs", "Neighbors of focused", callback = self.set_mark_mode)
227        OWGUI.appendRadioButton(ribg, self, "hubs", "Neighbours of selected", callback = self.set_mark_mode)
228        ib = OWGUI.indentedBox(ribg, orientation = 0)
229        self.ctrlMarkDistance = OWGUI.spin(ib, self, "markDistance", 0, 100, 1, label="Distance ", callback=(lambda h=2: self.set_mark_mode(h)))
230        #self.ctrlMarkFreeze = OWGUI.button(ib, self, "&Freeze", value="graph.freezeNeighbours", toggleButton = True)
231        OWGUI.widgetLabel(ribg, "Mark nodes with ...")
232        OWGUI.appendRadioButton(ribg, self, "hubs", "at least N connections", callback = self.set_mark_mode)
233        OWGUI.appendRadioButton(ribg, self, "hubs", "at most N connections", callback = self.set_mark_mode)
234        self.ctrlMarkNConnections = OWGUI.spin(OWGUI.indentedBox(ribg), self, "markNConnections", 0, 1000000, 1, label="N ", callback=(lambda h=4: self.set_mark_mode(h)))
235        OWGUI.appendRadioButton(ribg, self, "hubs", "more connections than any neighbour", callback = self.set_mark_mode)
236        OWGUI.appendRadioButton(ribg, self, "hubs", "more connections than avg neighbour", callback = self.set_mark_mode)
237        OWGUI.appendRadioButton(ribg, self, "hubs", "most connections", callback = self.set_mark_mode)
238        ib = OWGUI.indentedBox(ribg)
239        self.ctrlMarkNumber = OWGUI.spin(ib, self, "markNumber", 0, 1000000, 1, label="Number of nodes:", callback=(lambda h=8: self.set_mark_mode(h)))
240        OWGUI.widgetLabel(ib, "(More nodes are marked in case of ties)")
241        self.markInputRadioButton = OWGUI.appendRadioButton(ribg, self, "hubs", "Mark nodes given in the input signal", callback = self.set_mark_mode)
242        ib = OWGUI.indentedBox(ribg)
243        self.markInput = 0
244        self.markInputCombo = OWGUI.comboBox(ib, self, "markInput", callback=(lambda h=9: self.set_mark_mode(h)))
245        self.markInputRadioButton.setEnabled(False)
246       
247        ib = OWGUI.widgetBox(self.markTab, "General", orientation="vertical")
248        self.checkSendMarkedNodes = 0
249        OWGUI.checkBox(ib, self, 'checkSendMarkedNodes', 'Send marked nodes', callback = self.send_marked_nodes, disabled=0)
250       
251        G = self.networkCanvas.gui
252       
253        self.zoomSelectToolbar = G.zoom_select_toolbar(self.hcontroArea, orientation = Qt.Vertical,
254            buttons = 
255                [G.Spacing] * 2 + 
256                G.default_zoom_select_buttons + 
257                [
258                    G.Spacing,
259                    ("buttonM2S", "Add marked to selection", None, None, "marked_to_selected", 'Dlg_Mark2Sel'),
260                    ("buttonS2M", "Add selection to marked", None, None, "selected_to_marked", 'Dlg_Sel2Mark'),
261                    G.Spacing,
262                    ("buttonSEL", "Hide selected", None, None, "hideSelectedVertices", 'Dlg_UnselectedNodes'),
263                    ("buttonUN", "Hide unselected", None, None, "hideUnSelectedVertices", 'Dlg_SelectedNodes'),
264                    ("buttonSW", "Show all nodes", None, None, "showAllVertices", 'Dlg_clear'),
265                ])
266        self.zoomSelectToolbar.buttons[G.SendSelection].clicked.connect(self.send_data)
267        OWGUI.rubber(self.zoomSelectToolbar)
268       
269        ib = OWGUI.widgetBox(self.infoTab, "General")
270        OWGUI.label(ib, self, "Number of nodes: %(number_of_nodes_label)i")
271        OWGUI.label(ib, self, "Number of edges: %(number_of_edges_label)i")
272        OWGUI.label(ib, self, "Nodes per edge: %(verticesPerEdge).2f")
273        OWGUI.label(ib, self, "Edges per node: %(edgesPerVertex).2f")
274        OWGUI.label(ib, self, "Diameter: %(diameter).0f")
275        OWGUI.label(ib, self, "Clustering Coefficient: %(clustering_coefficient).1f%%")
276       
277        ib = OWGUI.widgetBox(self.infoTab, orientation="horizontal")
278       
279        OWGUI.button(ib, self, "Degree distribution", callback=self.showDegreeDistribution, debuggingEnabled=False)
280        OWGUI.button(ib, self, "Save network", callback=self.save_network, debuggingEnabled=False)
281        OWGUI.button(ib, self, "Save image", callback=self.networkCanvas.saveToFile, debuggingEnabled=False)
282       
283        #OWGUI.button(self.edgesTab, self, "Clustering", callback=self.clustering)
284        ib = OWGUI.widgetBox(self.infoTab, "Edit")
285        self.editAttribute = 0
286        self.editCombo = OWGUI.comboBox(ib, self, "editAttribute", label="Edit attribute:", orientation="horizontal")
287        self.editCombo.addItem("Select attribute")
288        self.editValue = ''
289        hb = OWGUI.widgetBox(ib, orientation="horizontal")
290        OWGUI.lineEdit(hb, self, "editValue", "Value:", orientation='horizontal')
291        OWGUI.button(hb, self, "Set", callback=self.edit)
292       
293        ib = OWGUI.widgetBox(self.infoTab, "Prototype")
294        ib.setVisible(True)
295       
296        OWGUI.lineEdit(ib, self, "organism", "Organism:", orientation='horizontal')
297       
298        self.nameComponentAttribute = 0
299        self.nameComponentCombo = OWGUI.comboBox(ib, self, "nameComponentAttribute", callback=self.nameComponents, label="Name components:", orientation="horizontal")
300        self.nameComponentCombo.addItem("Select attribute")
301       
302        self.showComponentAttribute = 0
303        self.showComponentCombo = OWGUI.comboBox(ib, self, "showComponentAttribute", callback=self.showComponents, label="Labels on components:", orientation="horizontal")
304        self.showComponentCombo.addItem("Select attribute")
305        OWGUI.checkBox(ib, self, 'showTextMiningInfo', "Show text mining info")
306       
307        #OWGUI.spin(ib, self, "rotateSteps", 1, 10000, 1, label="Rotate max steps: ")
308        OWGUI.spin(ib, self, "minComponentEdgeWidth", 0, 100, 1, label="Min component edge width: ", callback=(lambda changedMin=1: self.setComponentEdgeWidth(changedMin)))
309        OWGUI.spin(ib, self, "maxComponentEdgeWidth", 0, 200, 1, label="Max component edge width: ", callback=(lambda changedMin=0: self.setComponentEdgeWidth(changedMin)))
310       
311        self.attSelectionAttribute = 0
312        self.comboAttSelection = OWGUI.comboBox(ib, self, "attSelectionAttribute", label='Send attribute selection list:', orientation='horizontal', callback=self.sendAttSelectionList)
313        self.comboAttSelection.addItem("Select attribute")
314        self.autoSendAttributes = 0
315        OWGUI.checkBox(ib, self, 'autoSendAttributes', "auto send attributes", callback=self.setAutoSendAttributes)
316       
317        self.icons = self.createAttributeIconDict()
318        self.set_mark_mode()
319       
320        self.networkCanvas.gui.effects_box(self.performanceTab)
321       
322        self.verticesTab.layout().addStretch(1)
323        self.edgesTab.layout().addStretch(1)
324        self.markTab.layout().addStretch(1)
325        self.infoTab.layout().addStretch(1)
326        self.performanceTab.layout().addStretch(1)
327       
328        dlg = self.createColorDialog(self.colorSettings, self.selectedSchemaIndex)
329        self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
330        self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
331       
332        dlg = self.createColorDialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
333        self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
334        self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
335       
336        self.graph_layout_method()
337        self.set_font_size()
338        self.set_graph(None)
339        self.setMinimumWidth(900)
340       
341    def setComponentEdgeWidth(self, changedMin=True):
342        if self.networkCanvas is None:
343            return
344       
345        canvas = self.networkCanvas
346        if changedMin:
347            if self.maxComponentEdgeWidth < self.minComponentEdgeWidth:
348                self.maxComponentEdgeWidth = self.minComponentEdgeWidth
349        else:
350            if self.minComponentEdgeWidth > self.maxComponentEdgeWidth:
351                self.minComponentEdgeWidth = self.maxComponentEdgeWidth
352       
353        canvas.minComponentEdgeWidth = self.minComponentEdgeWidth
354        canvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
355        self.networkCanvas.updateCanvas()
356   
357    def setAutoSendAttributes(self):
358        print 'TODO setAutoSendAttributes'
359        #if self.autoSendAttributes:
360        #    self.networkCanvas.callbackSelectVertex = self.sendAttSelectionList
361        #else:
362        #    self.networkCanvas.callbackSelectVertex = None
363
364    def sendAttSelectionList(self):
365        if not self.graph is None:
366            vars = [x.name for x in self.graph_base.links_vars()]
367            if not self.comboAttSelection.currentText() in vars:
368                return
369            att = str(self.comboAttSelection.currentText())
370            vertices = self.networkCanvas.selected_nodes()
371           
372            if len(vertices) != 1:
373                return
374           
375            attributes = str(self.graph_base.items()[vertices[0]][att]).split(', ')
376        else:
377            attributes = None
378        self.send("Features", attributes)
379       
380    def edit(self):
381        if self.graph is None:
382            return
383       
384        vars = [x.name for x in self.graph_base.items_vars()]
385        if not self.editCombo.currentText() in vars:
386            return
387        att = str(self.editCombo.currentText())
388        vertices = self.networkCanvas.selected_nodes()
389       
390        if len(vertices) == 0:
391            return
392       
393        items = self.graph_base.items()
394        if items.domain[att].var_type == Orange.data.Type.Continuous:
395            for v in vertices:
396                items[v][att] = float(self.editValue)
397        else:
398            for v in vertices:
399                items[v][att] = str(self.editValue)
400   
401    def set_items_distance_matrix(self, matrix):
402        self.error()
403        self.warning()
404        self.information()
405       
406        self.cb_show_distances.setEnabled(0)
407        self.cb_show_component_distances.setEnabled(0)
408       
409        if matrix is None or self.graph_base is None:
410            self.items_matrix = None
411            self.networkCanvas.items_matrix = None
412            self.information('No graph found!')
413            return
414
415        if matrix.dim != self.graph_base.number_of_nodes():
416            self.error('The number of vertices does not match matrix size.')
417            self.items_matrix = None
418            self.networkCanvas.items_matrix = None
419            return
420       
421        self.items_matrix = matrix
422        self.networkCanvas.items_matrix = matrix
423        self.cb_show_distances.setEnabled(1)
424        self.cb_show_component_distances.setEnabled(1)
425       
426        if str(self.optMethod) in ['8', '9', '10']:
427            if self.items_matrix is not None and self.graph is not None and \
428            self.items_matrix.dim == self.graph.number_of_nodes():
429                self.optButton.setEnabled(True)
430                self.optButton.setChecked(True)
431                self.graph_layout()
432   
433    def send_marked_nodes(self):
434        if self.checkSendMarkedNodes:
435            markedNodes = self.networkCanvas.marked_nodes()
436           
437            if len(markedNodes) == 0:
438                self.send("Marked Items", None)
439                return
440           
441            if self.graph is not None and self.graph_base.items() is not None:
442                items = self.graph_base.items().getitems(markedNodes)
443                self.send("Marked Items", items)
444                return
445           
446            self.send("Marked Items", None)
447        else:
448            self.networkCanvas.send_marked_nodes = None
449            self.send("Marked Items", None)
450           
451    def showComponents(self):
452        if self.graph is None or self.graph_base.items() is None:
453            return
454       
455        vars = [x.name for x in self.graph_base.items_vars()]
456       
457        if not self.showComponentCombo.currentText() in vars:
458            self.networkCanvas.showComponentAttribute = None
459            self.lastNameComponentAttribute = ''
460        else:
461            self.networkCanvas.showComponentAttribute = self.showComponentCombo.currentText()     
462       
463        self.networkCanvas.drawComponentKeywords()
464       
465    def nameComponents(self):
466        """Names connected components of genes according to GO terms."""
467        self.progressBarFinished()
468        self.lastNameComponentAttribute = None
469       
470        if self.graph is None or self.graph_base.items() is None:
471            return
472       
473        vars = [x.name for x in self.graph_base.items_vars()]
474        if not self.nameComponentCombo.currentText() in vars:
475            return
476       
477        self.progressBarInit()
478        components = [c for c in Orange.network.nx.algorithms.components.connected_components(self.graph) if len(c) > 1]
479        if 'component name' in self.graph_base.items().domain:
480            keyword_table = self.graph_base.items()
481        else:
482            keyword_table = Orange.data.Table(Orange.data.Domain(Orange.data.variable.String('component name')), [[''] for i in range(len(self.graph_base.items()))]) 
483           
484        import obiGO 
485        ontology = obiGO.Ontology.Load(progressCallback=self.progressBarSet) 
486        annotations = obiGO.Annotations.Load(self.organism, ontology=ontology, progressCallback=self.progressBarSet)
487
488        allGenes = set([e[str(self.nameComponentCombo.currentText())].value for e in self.graph_base.items()])
489        foundGenesets = False
490        if len(annotations.geneNames & allGenes) < 1:
491            allGenes = set(reduce(operator.add, [e[str(self.nameComponentCombo.currentText())].value.split(', ') for e in self.graph_base.items()]))
492            if len(annotations.geneNames & allGenes) < 1:           
493                self.warning('no genes found')
494                return
495            else:
496                foundGenesets = True
497           
498        def rank(a, j, reverse=False):                   
499            if len(a) <= 0: return
500           
501            if reverse:               
502                a.sort(lambda x, y: 1 if x[j] > y[j] else -1 if x[j] < y[j] else 0)
503                top_value = a[0][j]
504                top_rank = len(a)
505                max_rank = float(len(a))
506                int_ndx = 0
507                for k in range(len(a)):
508                    if top_value < a[k][j]:
509                        top_value = a[k][j] 
510                        if k - int_ndx > 1:
511                            avg_rank = (a[int_ndx][j] + a[k-1][j]) / 2
512                            for l in range(int_ndx, k):
513                                a[l][j] = avg_rank
514                       
515                        int_ndx = k
516
517                    a[k][j] = top_rank / max_rank
518                    top_rank -= 1
519               
520                k += 1
521                if k - int_ndx > 1:
522                    avg_rank = (a[int_ndx][j] + a[k-1][j]) / 2
523                    for l in range(int_ndx, k):
524                        a[l][j] = avg_rank   
525               
526            else:
527                a.sort(lambda x, y: 1 if x[j] < y[j] else -1 if x[j] > y[j] else 0)
528                top_value = a[0][j]
529                top_rank = len(a)
530                max_rank = float(len(a))
531                int_ndx = 0
532                for k in range(len(a)):
533                    if top_value > a[k][j]:
534                        top_value = a[k][j] 
535                        if k - int_ndx > 1:
536                            avg_rank = (a[int_ndx][j] + a[k-1][j]) / 2
537                            for l in range(int_ndx, k):
538                                a[l][j] = avg_rank
539                       
540                        int_ndx = k
541
542                    a[k][j] = top_rank / max_rank
543                    top_rank -= 1
544               
545                k += 1
546                if k - int_ndx > 1:
547                    avg_rank = (a[int_ndx][j] + a[k-1][j]) / 2
548                    for l in range(int_ndx, k):
549                        a[l][j] = avg_rank
550       
551        for i in range(len(components)):
552            component = components[i]
553            if len(component) <= 1:
554                continue
555           
556            if foundGenesets:
557                genes = reduce(operator.add, [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value.split(', ') for v in component])
558            else:
559                genes = [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value for v in component]
560                   
561            res1 = annotations.GetEnrichedTerms(genes, aspect="P")
562            res2 = annotations.GetEnrichedTerms(genes, aspect="F")
563            res = res1.items() + res2.items()
564            #namingScore = [[(1-p_value) * (float(len(g)) / len(genes)) / (float(ref) / len(annotations.geneNames)), ontology.terms[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res.items() if p_value < 0.1]
565            #namingScore = [[(1-p_value) * len(g) / ref, ontology.terms[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res.items() if p_value < 0.1]
566           
567            namingScore = [[len(g), ref, p_value, ontology[GOId].name, len(g), ref, p_value] for GOId, (g, p_value, ref) in res if p_value < 0.1]
568            if len(namingScore) == 0:
569                continue
570           
571            annotated_genes = max([a[0] for a in namingScore])
572           
573            rank(namingScore, 1, reverse=True)
574            rank(namingScore, 2, reverse=True)
575            rank(namingScore, 0)
576           
577            namingScore = [[10 * rank_genes + 0.5 * rank_ref + rank_p_value, name, g, ref, p_value] for rank_genes, rank_ref, rank_p_value, name, g, ref, p_value in namingScore]
578            namingScore.sort(reverse=True)
579           
580            if len(namingScore) < 1:
581                print "warning. no annotations found for group of genes: " + ", ".join(genes)
582                continue
583            elif len(namingScore[0]) < 2:
584                print "warning. error computing score for group of genes: " + ", ".join(genes)
585                continue
586           
587            for v in component:
588                name = str(namingScore[0][1])
589                attrs = "%d/%d, %d, %lf" % (namingScore[0][2], annotated_genes, namingScore[0][3], namingScore[0][4])
590                info = ''
591                if self.showTextMiningInfo:
592                    info = "\n" + attrs + "\n" + str(namingScore[0][0])
593                keyword_table[v]['component name'] = name + info
594           
595            self.progressBarSet(i*100.0/len(components))
596               
597        self.lastNameComponentAttribute = self.nameComponentCombo.currentText()
598        self.setItems(Orange.data.Table([self.graph_base.items(), keyword_table]))
599        self.progressBarFinished()   
600           
601    def _set_canvas_attr(self, attr, value):
602        setattr(self.networkCanvas, attr, value)
603        self.networkCanvas.updateCanvas()
604   
605    def _set_curve_attr(self, attr, value):
606        setattr(self.networkCanvas.networkCurve, attr, value)
607        self.networkCanvas.updateCanvas()
608               
609    def setSearchStringTimer(self):
610        self.hubs = 1
611        self.searchStringTimer.stop()
612        self.searchStringTimer.start(1000)
613         
614    def set_mark_mode(self, i=None):
615        self.searchStringTimer.stop()
616        if not i is None:
617            self.hubs = i
618       
619        QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.networkCanvas.mark_on_selection_changed)
620        QObject.disconnect(self.networkCanvas, SIGNAL('point_hovered(Point*)'), self.networkCanvas.mark_on_focus_changed)
621       
622        if self.graph is None:
623            return
624       
625        hubs = self.hubs
626       
627        if hubs in [0,1,2,3]:
628            if hubs == 0:
629                self.networkCanvas.networkCurve.clear_node_marks()
630            elif hubs == 1:
631                #print "mark on given label"
632                txt = self.markSearchString
633               
634                toMark = set(i for i, values in enumerate(self.graph_base.items()) if txt.lower() in " ".join([str(values[ndx]).decode("ascii", "ignore").lower() for ndx in range(len(self.graph_base.items().domain)) + self.graph_base.items().domain.getmetas().keys()]))
635                toMark = toMark.intersection(self.graph.nodes())
636                self.networkCanvas.networkCurve.clear_node_marks()
637                self.networkCanvas.networkCurve.set_node_marks(dict((i, True) for i in toMark))
638            elif hubs == 2:
639                #print "mark on focus"
640                self.networkCanvas.mark_neighbors = self.markDistance
641                QObject.connect(self.networkCanvas, SIGNAL('point_hovered(Point*)'), self.networkCanvas.mark_on_focus_changed)
642            elif hubs == 3:
643                #print "mark selected"
644                self.networkCanvas.mark_neighbors = self.markDistance
645                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.networkCanvas.mark_on_selection_changed)
646                self.networkCanvas.mark_on_selection_changed()
647               
648        elif hubs in [4,5,6,7,8,9]:
649           
650            powers = sorted(self.graph.degree_iter(), key=itemgetter(1), reverse=True)
651           
652            if hubs == 4:
653                #print "mark at least N connections"
654                N = self.markNConnections
655                self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
656                    d >= N else (i, False) for i, d in powers))
657            elif hubs == 5:
658                #print "mark at most N connections"
659                N = self.markNConnections
660                self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
661                    d <= N else (i, False) for i, d in powers))
662            elif hubs == 6:
663                #print "mark more than any"
664                self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
665                    d > max([0]+self.graph.degree(self.graph.neighbors(i)).values()) \
666                    else (i, False) for i,d in powers ))
667            elif hubs == 7:
668                #print "mark more than avg"
669                self.networkCanvas.networkCurve.set_node_marks(dict((i, True) if \
670                    d > statc.mean([0]+self.graph.degree(self.graph.neighbors(i)).values()) \
671                    else (i, False) for i,d in powers ))
672                self.networkCanvas.replot()
673            elif hubs == 8:
674                #print "mark most"
675                self.networkCanvas.networkCurve.clear_node_marks()
676               
677                if self.markNumber < 1:
678                    return
679               
680                cut = self.markNumber
681                cutPower = powers[cut-1][1]
682                while cut < len(powers) and powers[cut][1] == cutPower:
683                    cut += 1
684   
685                self.networkCanvas.networkCurve.clear_node_marks()
686                self.networkCanvas.networkCurve.set_node_marks(dict((i, True) for \
687                    i,d in powers[:cut]))
688               
689            elif hubs == 9:
690                var = str(self.markInputCombo.currentText())
691                if self.markInputItems is not None and len(self.markInputItems) > 0:
692                    values = [str(x[var]).strip().upper() for x in self.markInputItems]
693                    tomark = dict((x, True) for x in self.graph.nodes() if str(self.graph_base.items()[x][var]).strip().upper() in values)
694                    self.networkCanvas.networkCurve.clear_node_marks()
695                    self.networkCanvas.networkCurve.set_node_marks(tomark)
696                   
697                else:
698                    self.networkCanvas.networkCurve.clear_node_marks()     
699       
700        self.nMarked = len(self.networkCanvas.marked_nodes())
701        self.send_marked_nodes()
702       
703    def testRefresh(self):
704        start = time.time()
705        self.networkCanvas.replot()
706        stop = time.time()   
707        print "replot in " + str(stop - start)
708       
709    def save_network(self):
710#        if self.networkCanvas is None or self.graph is None:
711#            return
712#       
713#        filename = QFileDialog.getSaveFileName(self, 'Save Network File', '', 'NetworkX graph as Python pickle (*.gpickle)\nPajek network (*.net)\nGML network (*.gml)')
714#        if filename:
715#            fn = ""
716#            head, tail = os.path.splitext(str(filename))
717#            if not tail:
718#                fn = head + ".net"
719#            else:
720#                fn = str(filename)
721#           
722#            for i in range(self.graph.number_of_nodes()):
723#                node = self.graph.node[i]
724#                node['x'] = self.layout.coors[0][i]
725#                node['y'] = self.layout.coors[1][i]
726#
727#            Orange.network.readwrite.write(self.graph, fn)
728        pass
729           
730    def send_data(self):
731        selected_nodes = self.networkCanvas.selected_nodes()
732        graph = self.graph_base.subgraph(selected_nodes)
733       
734        if graph is not None:
735            self.send("Selected Items", graph.items())
736           
737            nodes = self.networkCanvas.not_selected_nodes()
738            if len(nodes) > 0 and self.graph_base.items() is not None:
739                self.send("Other Items", self.graph_base.items().getitems(nodes))
740            else:
741                self.send("Other Items", None)
742               
743            self.send("Selected Network", graph)
744        else:
745            self.send("Selected Items", None)
746            self.send("Other Items", None)
747            self.send("Selected Network", None)
748           
749        matrix = None if self.items_matrix is None else self.items_matrix.getitems(selected_nodes)
750        self.send("Distance Matrix", matrix)
751               
752    def setCombos(self):
753        vars = self.graph_base.items_vars()
754        edgeVars = self.graph_base.links_vars()
755        lastLabelColumns = self.lastLabelColumns
756        lastTooltipColumns = self.lastTooltipColumns
757       
758        self.clearCombos()
759       
760        self.attributes = [(var.name, var.varType) for var in vars]
761        self.edgeAttributes = [(var.name, var.varType) for var in edgeVars]
762       
763        for var in vars:
764            if var.varType in [Orange.data.Type.Discrete, Orange.data.Type.Continuous]:
765                self.colorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
766               
767            if var.varType in [Orange.data.Type.String] and hasattr(self.graph, 'items') and self.graph_base.items() is not None and len(self.graph_base.items()) > 0:
768               
769                value = self.graph_base.items()[0][var].value
770               
771                # can value be a list?
772                try:
773                    if type(eval(value)) == type([]):
774                        self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
775                        continue
776                except:
777                    pass
778               
779                if len(value.split(',')) > 1:
780                    self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), "num of " + unicode(var.name))
781               
782            elif var.varType in [Orange.data.Type.Continuous]:
783                self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
784
785            self.nameComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
786            self.showComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
787            self.editCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
788            self.comboAttSelection.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
789       
790        for var in edgeVars:
791            if var.varType in [Orange.data.Type.Discrete, Orange.data.Type.Continuous]:
792                self.edgeColorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
793               
794        for i in range(self.vertexSizeCombo.count()):
795            if self.lastVertexSizeColumn == self.vertexSizeCombo.itemText(i):
796                self.vertexSize = i
797                break
798           
799        for i in range(self.colorCombo.count()):
800            if self.lastColorColumn == self.colorCombo.itemText(i):
801                self.color = i
802                break
803
804        for i in range(self.attListBox.count()):
805            if str(self.attListBox.item(i).text()) in lastLabelColumns:
806                self.attListBox.item(i).setSelected(1)
807               
808        for i in range(self.tooltipListBox.count()):
809            if str(self.tooltipListBox.item(i).text()) in lastTooltipColumns:
810                self.tooltipListBox.item(i).setSelected(1)
811           
812        self.lastLabelColumns = lastLabelColumns
813        self.lastTooltipColumns = lastTooltipColumns
814       
815    def clearCombos(self):
816        self.attributes = []
817        self.edgeAttributes = []
818       
819        self.colorCombo.clear()
820        self.vertexSizeCombo.clear()
821        self.nameComponentCombo.clear()
822        self.showComponentCombo.clear()
823        self.edgeColorCombo.clear()
824        self.editCombo.clear()
825        self.comboAttSelection.clear()
826       
827        self.colorCombo.addItem("(same color)")
828        self.edgeColorCombo.addItem("(same color)")
829        self.vertexSizeCombo.addItem("(same size)")
830        self.nameComponentCombo.addItem("Select attribute")
831        self.showComponentCombo.addItem("Select attribute")
832        self.editCombo.addItem("Select attribute")
833        self.comboAttSelection.addItem("Select attribute")
834     
835    def compute_network_info(self):
836        self.nShown = self.graph.number_of_nodes()
837       
838        if self.graph.number_of_edges() > 0:
839            self.verticesPerEdge = float(self.graph.number_of_nodes()) / float(self.graph.number_of_edges())
840        else:
841            self.verticesPerEdge = 0
842           
843        if self.graph.number_of_nodes() > 0:
844            self.edgesPerVertex = float(self.graph.number_of_edges()) / float(self.graph.number_of_nodes())
845        else:
846            self.edgesPerVertex = 0
847       
848        undirected_graph = self.graph.to_undirected() if self.graph.is_directed() else self.graph
849        components = Orange.network.nx.algorithms.components.connected_components(undirected_graph)
850        if len(components) > 1:
851            self.diameter = float('nan')
852        else:
853            try:
854                if self.graph.number_of_nodes() > 1:
855                    self.diameter = Orange.network.nx.algorithms.distance_measures.diameter(self.graph)
856                else:
857                    self.diameter = -1
858            except Orange.network.nx.NetworkXError as err:
859                if 'infinite path length' in err.message:
860                    self.diameter = float('inf')
861                else:
862                    raise err
863        if self.graph.is_multigraph():
864            self.clustering_coefficient = -1
865        else:
866            self.clustering_coefficient = Orange.network.nx.algorithms.cluster.average_clustering(undirected_graph) * 100
867     
868    def change_graph(self, newgraph):
869        self.information()
870       
871        # if graph has more nodes and edges than pixels in 1600x1200 display,
872        # it is too big to visualize!
873        if newgraph.number_of_nodes() + newgraph.number_of_edges() > 50000:
874            self.information('New graph is too big to visualize. Keeping the old graph.')
875            return
876       
877        self.graph = newgraph
878       
879        self.number_of_nodes_label = self.graph.number_of_nodes()
880        self.number_of_edges_label = self.graph.number_of_edges()
881       
882        if not self.networkCanvas.change_graph(self.graph):
883            return
884       
885        self.compute_network_info()
886       
887        t = 1.13850193174e-008 * (self.graph.number_of_nodes()**2 + self.graph.number_of_edges())
888        self.frSteps = int(2.0 / t)
889        if self.frSteps <   1: self.frSteps = 1
890        if self.frSteps > 100: self.frSteps = 100
891#       
892#        if self.frSteps < 10:
893#            self.networkCanvas.use_antialiasing = 0
894#            self.networkCanvas.use_animations = 0
895#            self.minVertexSize = 5
896#            self.maxVertexSize = 5
897#            self.maxLinkSize = 1
898#            self.optMethod = 0
899#            self.graph_layout_method()
900       
901        animation_enabled = self.networkCanvas.animate_points;
902        self.networkCanvas.animate_points = False;
903       
904        self.set_node_sizes()
905        self.set_node_colors()
906        self.set_edge_sizes()
907        self.set_edge_colors()
908           
909        self.clickedAttLstBox()
910        self.clickedTooltipLstBox()
911        self.clickedEdgeLabelListBox()
912       
913        self.networkCanvas.replot()
914       
915        self.networkCanvas.animate_points = animation_enabled
916        qApp.processEvents()
917        self.networkCanvas.networkCurve.layout_fr(100, weighted=False, smooth_cooling=True)
918        self.networkCanvas.update_canvas()       
919
920    def set_graph_none(self):
921        self.graph = None
922        self.graph_base = None
923        self.clearCombos()
924        self.number_of_nodes_label = -1
925        self.number_of_edges_label = -1
926        self._items = None
927        self._links = None
928        self.set_items_distance_matrix(None)
929        self.networkCanvas.set_graph(None)
930
931    def set_graph(self, graph, curve=None):
932        self.information()
933        self.warning()
934        self.error()
935       
936        if graph is None:
937            self.set_graph_none()
938            return
939       
940        if graph.number_of_nodes() < 2:
941            self.set_graph_none()
942            self.information('I\'m not really in a mood to visualize just one node. Try again tomorrow.')
943            return
944       
945        self.graph_base = graph
946       
947        if self._network_view is not None:
948            graph = self._network_view.init_network(graph)
949       
950        self.graph = graph
951       
952        # if graph has more nodes and edges than pixels in 1600x1200 display,
953        # it is too big to visualize!
954        if self.graph.number_of_nodes() + self.graph.number_of_edges() > 50000:
955            self.set_graph_none()
956            self.error('Graph is too big to visualize. Try using one of the network views.')
957            return
958       
959        if self.items_matrix is not None and self.items_matrix.dim != self.graph_base.number_of_nodes():
960            self.set_items_distance_matrix(None)
961       
962        self.number_of_nodes_label = self.graph.number_of_nodes()
963        self.number_of_edges_label = self.graph.number_of_edges()
964       
965        self.networkCanvas.set_graph(self.graph, curve, items=self.graph_base.items(), links=self.graph_base.links())
966       
967        if self._items is not None and 'x' in self._items.domain and 'y' in self._items.domain:
968            positions = dict((node, (self._items[node]['x'].value, self._items[node]['y'].value)) \
969                         for node in self.graph if self._items[node]['x'].value != '?' \
970                         and self._items[node]['y'].value != '?')
971           
972            self.networkCanvas.networkCurve.set_node_coordinates(positions)
973
974       
975        self.networkCanvas.showEdgeLabels = self.showEdgeLabels
976        self.networkCanvas.maxEdgeSize = self.maxLinkSize
977        self.networkCanvas.minComponentEdgeWidth = self.minComponentEdgeWidth
978        self.networkCanvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
979        self.networkCanvas.set_labels_on_marked_only(self.labelsOnMarkedOnly)
980       
981        self.compute_network_info()
982        self.setCombos()
983           
984        lastNameComponentAttributeFound = False
985        for i in range(self.nameComponentCombo.count()):
986            if self.lastNameComponentAttribute == self.nameComponentCombo.itemText(i):
987                lastNameComponentAttributeFound = True
988                self.nameComponentAttribute = i
989                self.nameComponents()
990                self.showComponentAttribute = self.showComponentCombo.count() - 1
991                self.showComponents()
992                break
993           
994        if not lastNameComponentAttributeFound:
995            self.lastNameComponentAttribute = ''
996       
997        self.showComponentAttribute = None
998
999        t = 1.13850193174e-008 * (self.graph.number_of_nodes()**2 + self.graph.number_of_edges())
1000        self.frSteps = int(2.0 / t)
1001        if self.frSteps <   1: self.frSteps = 1
1002        if self.frSteps > 100: self.frSteps = 100
1003       
1004        # if graph is large, set random layout, min vertex size, min edge size
1005        if self.frSteps < 10:
1006            self.networkCanvas.update_antialiasing(False)
1007            self.networkCanvas.update_animations(False)
1008            self.minVertexSize = 5
1009            self.maxVertexSize = 5
1010            self.maxLinkSize = 1
1011            self.optMethod = 0
1012            self.graph_layout_method()           
1013       
1014        self.networkCanvas.labelsOnMarkedOnly = self.labelsOnMarkedOnly
1015        self.networkCanvas.showWeights = self.showWeights
1016           
1017        self.set_node_sizes()
1018        self.set_node_colors()
1019        self.set_edge_sizes()
1020        self.set_edge_colors()
1021           
1022        self.clickedAttLstBox()
1023        self.clickedTooltipLstBox()
1024        self.clickedEdgeLabelListBox()
1025       
1026        self.optButton.setChecked(1)
1027        self.graph_layout()       
1028       
1029    def set_network_view(self, nxView):
1030        self.error()
1031        self.warning()
1032        self.information()
1033       
1034        if self.graph is None:
1035            self.information('Do not forget to add a graph!')
1036           
1037        if self._network_view is not None:
1038            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
1039           
1040        self._network_view = nxView
1041       
1042        if self._network_view is not None:
1043            self._network_view.set_nx_explorer(self)
1044       
1045        self.set_graph(self.graph_base)
1046       
1047        if self._network_view is not None:
1048            QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
1049       
1050    def setItems(self, items=None):
1051        self.error()
1052        self.warning()
1053        self.information()
1054       
1055        if self.graph is None or items is None:
1056            self.warning('No graph found!')
1057            return
1058       
1059        if len(items) != self.graph_base.number_of_nodes():
1060            self.error('ExampleTable items must have one example for each vertex.')
1061            return
1062       
1063        self.graph_base.set_items(items)
1064       
1065        self.set_node_sizes()
1066        self.networkCanvas.items = items
1067        self.networkCanvas.showWeights = self.showWeights
1068        self.networkCanvas.showEdgeLabels = self.showEdgeLabels
1069        self.setCombos()
1070        #self.networkCanvas.updateData()
1071       
1072    def markItems(self, items):
1073        self.markInputCombo.clear()
1074        self.markInputRadioButton.setEnabled(False)
1075        self.markInputItems = items
1076       
1077        self.error()
1078        self.warning()
1079        self.information()
1080       
1081        if self.graph is None or self.graph_base.items() is None or items is None:
1082            self.warning('No graph found or no items attached to the graph.')
1083            return
1084       
1085        if len(items) > 0:
1086            lstOrgDomain = [x.name for x in self.graph_base.items().domain] + [self.graph_base.items().domain[x].name for x in self.graph_base.items().domain.getmetas()]
1087            lstNewDomain = [x.name for x in items.domain] + [items.domain[x].name for x in items.domain.getmetas()]
1088            commonVars = set(lstNewDomain) & set(lstOrgDomain)
1089
1090            if len(commonVars) > 0:
1091                for var in commonVars:
1092                    orgVar = self.graph_base.items().domain[var]
1093                    mrkVar = items.domain[var]
1094
1095                    if orgVar.varType == mrkVar.varType and orgVar.varType == Orange.data.Type.String:
1096                        self.markInputCombo.addItem(self.icons[orgVar.varType], unicode(orgVar.name))
1097                        self.markInputRadioButton.setEnabled(True)
1098               
1099                        self.set_mark_mode(9)
1100             
1101    def setExampleSubset(self, subset):
1102        print "TODO: not yet implemented"
1103        if self.graph is None:
1104            return
1105       
1106        self.warning('')
1107        hiddenNodes = []
1108       
1109        if subset is not None:
1110            try:
1111                expected = 1
1112                for row in subset:
1113                    index = int(row['index'].value)
1114                    if expected != index:
1115                        hiddenNodes += range(expected-1, index-1)
1116                        expected = index + 1
1117                    else:
1118                        expected += 1
1119                       
1120                hiddenNodes += range(expected-1, self.graph.number_of_nodes())
1121               
1122                self.networkCanvas.setHiddenNodes(hiddenNodes)
1123            except:
1124                self.warning('"index" attribute does not exist in "items" table.')
1125                   
1126    def showDegreeDistribution(self):
1127        if self.graph is None:
1128            return
1129       
1130        from matplotlib import rcParams
1131        import pylab as p
1132       
1133        x = self.graph.degree().values()
1134        nbins = len(set(x))
1135        if nbins > 500:
1136          bbins = 500
1137       
1138        # the histogram of the data
1139        n, bins, patches = p.hist(x, nbins)
1140       
1141        p.xlabel('Degree')
1142        p.ylabel('No. of nodes')
1143        p.title(r'Degree distribution')
1144       
1145        p.show()
1146       
1147    def setColors(self):
1148        dlg = self.createColorDialog(self.colorSettings, self.selectedSchemaIndex)
1149        if dlg.exec_():
1150            self.colorSettings = dlg.getColorSchemas()
1151            self.selectedSchemaIndex = dlg.selectedSchemaIndex
1152            self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
1153            self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
1154           
1155            self.set_node_colors()
1156           
1157    def setEdgeColorPalette(self):
1158        dlg = self.createColorDialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
1159        if dlg.exec_():
1160            self.edgeColorSettings = dlg.getColorSchemas()
1161            self.selectedEdgeSchemaIndex = dlg.selectedSchemaIndex
1162            self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
1163            self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
1164           
1165            self.set_edge_colors()
1166   
1167    def createColorDialog(self, colorSettings, selectedSchemaIndex):
1168        c = OWColorPalette.ColorPaletteDlg(self, "Color Palette")
1169        c.createDiscretePalette("discPalette", "Discrete Palette")
1170        c.createContinuousPalette("contPalette", "Continuous Palette")
1171        c.setColorSchemas(colorSettings, selectedSchemaIndex)
1172        return c
1173   
1174    """
1175    Layout Optimization
1176    """
1177   
1178    def graph_layout(self):
1179        if self.graph is None:   #grafa se ni
1180            self.optButton.setChecked(False)
1181            return
1182       
1183        if not self.optButton.isChecked() and not self.optMethod in [2,3,9,10]:
1184            self.optButton.setChecked(False)
1185            return
1186       
1187        qApp.processEvents()
1188       
1189        if self.optMethod == 1:
1190            self.networkCanvas.networkCurve.random()
1191        elif self.optMethod == 2:
1192            self.graph_layout_fr(False)
1193        elif self.optMethod == 3:
1194            self.graph_layout_fr(True)
1195        elif self.optMethod == 4:
1196            self.graph_layout_fr_radial()
1197        elif self.optMethod == 5:
1198            self.networkCanvas.networkCurve.circular(NetworkCurve.circular_crossing)
1199        elif self.optMethod == 6:
1200            self.networkCanvas.networkCurve.circular(NetworkCurve.circular_original)
1201        elif self.optMethod == 7:
1202            self.networkCanvas.networkCurve.circular(NetworkCurve.circular_random)
1203        elif self.optMethod == 8:
1204            self.graph_layout_pivot_mds()
1205        elif self.optMethod == 9:
1206            self.graph_layout_fragviz()
1207        elif self.optMethod == 10: 
1208            self.graph_layout_mds()
1209           
1210        self.optButton.setChecked(False)
1211        self.networkCanvas.update_canvas()
1212        qApp.processEvents()
1213       
1214    def graph_layout_method(self, method=None):
1215        self.information()
1216        self.stepsSpin.label.setText('Iterations: ')
1217        self.optButton.setEnabled(True)
1218        self.cb_opt_from_curr.setEnabled(False)
1219       
1220        if method is not None:
1221            self.optMethod = method
1222           
1223        if str(self.optMethod) == '0':
1224            self.optButton.setEnabled(False)
1225        else:
1226            self.optButton.setEnabled(True)
1227           
1228        if str(self.optMethod) in ['2', '3', '4']:
1229            self.stepsSpin.setEnabled(True)
1230           
1231        elif str(self.optMethod) in ['8', '9', '10']:
1232            if str(self.optMethod) == '8': 
1233                self.stepsSpin.label.setText('Pivots: ')
1234           
1235            if str(self.optMethod) in ['9', '10']: 
1236                self.cb_opt_from_curr.setEnabled(True)
1237               
1238            self.stepsSpin.setEnabled(True)
1239           
1240            if self.items_matrix is None:
1241                self.information('Set distance matrix to input signal')
1242                self.optButton.setEnabled(False)
1243                return
1244            if self.graph is None:
1245                self.information('No network found')
1246                self.optButton.setEnabled(False)
1247                return
1248            if self.items_matrix.dim != self.graph.number_of_nodes():
1249                self.error('Distance matrix dimensionality must equal number of vertices')
1250                self.optButton.setEnabled(False)
1251                return
1252        else:
1253            self.stepsSpin.setEnabled(False)
1254            self.optButton.setChecked(True)
1255            self.graph_layout()
1256       
1257   
1258    def mdsProgress(self, avgStress, stepCount):   
1259        #self.drawForce()
1260
1261        #self.mdsInfoA.setText("Avg. Stress: %.20f" % avgStress)
1262        #self.mdsInfoB.setText("Num. steps: %i" % stepCount)
1263        self.progressBarSet(int(stepCount * 100 / self.frSteps))
1264        qApp.processEvents()
1265       
1266    def graph_layout_fragviz(self):
1267        if self.items_matrix is None:
1268            self.information('Set distance matrix to input signal')
1269            self.optButton.setChecked(False)
1270            return
1271       
1272        if self.layout is None:
1273            self.information('No network found')
1274            self.optButton.setChecked(False)
1275            return
1276       
1277        if self.items_matrix.dim != self.graph.number_of_nodes():
1278            self.error('Distance matrix dimensionality must equal number of vertices')
1279            self.optButton.setChecked(False)
1280            return
1281       
1282        if not self.optButton.isChecked():
1283            self.networkCanvas.networkCurve.stopMDS = True
1284            self.optButton.setChecked(False)
1285            self.optButton.setText("Optimize layout")
1286            return
1287       
1288        self.optButton.setText("Stop")
1289        self.progressBarInit()
1290        qApp.processEvents()
1291
1292        if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1293            matrix = self.items_matrix
1294        else:
1295            matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1296       
1297        self.networkCanvas.networkCurve.layout_fragviz(self.frSteps, matrix, self.graph, self.mdsProgress, self.opt_from_curr)
1298
1299        self.optButton.setChecked(False)
1300        self.optButton.setText("Optimize layout")
1301        self.progressBarFinished()
1302       
1303    def graph_layout_mds(self):
1304        if self.items_matrix is None:
1305            self.information('Set distance matrix to input signal')
1306            self.optButton.setChecked(False)
1307            return
1308       
1309        if self.layout is None:
1310            self.information('No network found')
1311            self.optButton.setChecked(False)
1312            return
1313       
1314        if self.items_matrix.dim != self.graph.number_of_nodes():
1315            self.error('Distance matrix dimensionality must equal number of vertices')
1316            self.optButton.setChecked(False)
1317            return
1318       
1319        if not self.optButton.isChecked():
1320            self.networkCanvas.networkCurve.stopMDS = True
1321            self.optButton.setChecked(False)
1322            self.optButton.setText("Optimize layout")
1323            return
1324       
1325        self.optButton.setText("Stop")
1326        self.progressBarInit()
1327        qApp.processEvents()
1328       
1329        if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1330            matrix = self.items_matrix
1331        else:
1332            matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1333       
1334        self.networkCanvas.networkCurve.layout_mds(self.frSteps, matrix, self.mdsProgress, self.opt_from_curr)
1335
1336        self.optButton.setChecked(False)
1337        self.optButton.setText("Optimize layout")
1338        self.progressBarFinished()
1339       
1340    def graph_layout_fr(self, weighted):
1341        if self.graph is None:
1342            return
1343             
1344        if not self.optButton.isChecked():
1345            self.networkCanvas.networkCurve.stop_optimization()
1346            self.optButton.setChecked(False)
1347            self.optButton.setText("Optimize layout")
1348            return
1349       
1350        self.optButton.setText("Stop")
1351        qApp.processEvents()
1352        self.networkCanvas.networkCurve.layout_fr(self.frSteps, False)
1353        self.networkCanvas.update_canvas()
1354        self.optButton.setChecked(False)
1355        self.optButton.setText("Optimize layout")
1356               
1357    def graph_layout_fr_radial(self):
1358        if self.graph is None:   #grafa se ni
1359            return
1360       
1361#        #print "F-R Radial"
1362#        k = 1.13850193174e-008
1363#        nodes = self.graph.number_of_nodes()
1364#        t = k * nodes * nodes
1365#        refreshRate = int(5.0 / t)
1366#        if refreshRate <    1: refreshRate = 1
1367#        if refreshRate > 1500: refreshRate = 1500
1368#        #print "refreshRate: " + str(refreshRate)
1369#       
1370#        tolerance = 5
1371#        initTemp = 100
1372#        centerNdx = 0
1373#       
1374#        selection = self.networkCanvas.getSelection()
1375#        if len(selection) > 0:
1376#            centerNdx = selection[0]
1377#           
1378#        #print "center ndx: " + str(centerNdx)
1379#        initTemp = self.layout.fr_radial(centerNdx, refreshRate, initTemp)
1380#        self.networkCanvas.circles = [10000 / 12, 10000/12*2, 10000/12*3]#, 10000/12*4, 10000/12*5]
1381#        #self.networkCanvas.circles = [100, 200, 300]
1382#        self.networkCanvas.updateCanvas()
1383#        self.networkCanvas.circles = []
1384           
1385    def graph_layout_pivot_mds(self):
1386        self.information()
1387       
1388        if self.items_matrix is None:
1389            self.information('Set distance matrix to input signal')
1390            return
1391       
1392        if self.graph_base is None:
1393            self.information('No network found')
1394            return
1395       
1396        if self.items_matrix.dim != self.graph_base.number_of_nodes():
1397            self.error('The number of vertices does not match matrix size.')
1398            return
1399       
1400        self.frSteps = min(self.frSteps, self.graph.number_of_nodes())
1401        qApp.processEvents()
1402       
1403        if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1404            matrix = self.items_matrix
1405        else:
1406            matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1407       
1408        mds = orngMDS.PivotMDS(matrix, self.frSteps)
1409        x,y = mds.optimize()
1410        xy = zip(list(x), list(y))
1411        coors = dict(zip(sorted(self.graph.nodes()), xy))
1412        self.networkCanvas.networkCurve.set_node_coordinates(coors)
1413        self.networkCanvas.update_canvas()
1414
1415    """
1416    Network Visualization
1417    """
1418    def clickedAttLstBox(self):
1419        if self.graph is None:
1420            return
1421       
1422        self.lastLabelColumns = [self.attributes[i][0] for i in self.markerAttributes]
1423        self.networkCanvas.set_node_labels(self.lastLabelColumns)
1424        self.networkCanvas.replot()
1425 
1426    def clickedTooltipLstBox(self):
1427        if self.graph is None:
1428            return
1429       
1430        self.lastTooltipColumns = [self.attributes[i][0] for i in self.tooltipAttributes]
1431        self.networkCanvas.set_tooltip_attributes(self.lastTooltipColumns)
1432        self.networkCanvas.replot()
1433       
1434    def clickedEdgeLabelListBox(self):
1435        if self.graph is None:
1436            return
1437       
1438        self.lastEdgeLabelAttributes = set([self.edgeAttributes[i][0] for i in self.edgeLabelAttributes])
1439        self.networkCanvas.set_edge_labels(self.lastEdgeLabelAttributes)
1440        self.networkCanvas.replot()
1441
1442    def set_node_colors(self):
1443        if self.graph is None:
1444            return
1445       
1446        self.networkCanvas.set_node_colors(self.colorCombo.currentText())
1447        self.lastColorColumn = self.colorCombo.currentText()
1448       
1449    def set_edge_colors(self):
1450        if self.graph is None:
1451            return
1452       
1453        self.networkCanvas.set_edge_colors(self.edgeColorCombo.currentText())
1454        self.lastEdgeColorColumn = self.edgeColorCombo.currentText()
1455                 
1456    def set_edge_sizes(self):
1457        if self.graph is None:
1458            return
1459       
1460        self.networkCanvas.networkCurve.set_edge_sizes(self.maxLinkSize)
1461        self.networkCanvas.replot()
1462   
1463    def set_node_sizes(self):
1464        if self.graph is None or self.networkCanvas is None:
1465            return
1466       
1467        if self.minVertexSize > self.maxVertexSize:
1468            self.maxVertexSize = self.minVertexSize
1469       
1470        items = self.graph_base.items()
1471       
1472        if items is None:
1473            self.networkCanvas.networkCurve.set_node_sizes({}, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1474            return
1475       
1476        self.lastVertexSizeColumn = self.vertexSizeCombo.currentText()
1477        column = str(self.vertexSizeCombo.currentText())
1478       
1479        values = {}
1480        if column in items.domain or (column.startswith("num of ") and column.replace("num of ", "") in items.domain):
1481            if column in items.domain:
1482                values = dict((x, items[x][column].value) for x in self.graph if not items[x][column].isSpecial())
1483            else:
1484                values = dict((x, len(items[x][column.replace("num of ", "")].value.split(','))) for x in self.graph)
1485       
1486        if len(values) == 0:
1487            values = dict((node, 1.) for node in self.graph)
1488           
1489        if self.invertSize:
1490            maxval = max(values.itervalues())
1491            values.update((key, maxval-val) for key, val in values.iteritems())
1492            self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1493        else:
1494            self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1495       
1496        self.networkCanvas.replot()
1497       
1498    def set_font_size(self):
1499        if self.networkCanvas is None:
1500            return
1501       
1502        font = self.networkCanvas.font()
1503        font.setPointSize(self.fontSize)
1504        self.networkCanvas.setFont(font)
1505        self.networkCanvas.fontSize = font
1506       
1507               
1508    def sendReport(self):
1509        self.reportSettings("Graph data",
1510                            [("Number of vertices", self.graph.number_of_nodes()),
1511                             ("Number of edges", self.graph.number_of_edges()),
1512                             ("Vertices per edge", "%.3f" % self.verticesPerEdge),
1513                             ("Edges per vertex", "%.3f" % self.edgesPerVertex),
1514                             ("Diameter", self.diameter),
1515                             ("Clustering Coefficient", "%.1f%%" % self.clustering_coefficient)
1516                             ])
1517        if self.color or self.vertexSize or self.markerAttributes or self.edgeColor:
1518            self.reportSettings("Visual settings",
1519                                [self.color and ("Vertex color", self.colorCombo.currentText()),
1520                                 self.vertexSize and ("Vertex size", str(self.vertexSizeCombo.currentText()) + " (inverted)" if self.invertSize else ""),
1521                                 self.markerAttributes and ("Labels", ", ".join(self.attributes[i][0] for i in self.markerAttributes)),
1522                                 self.edgeColor and ("Edge colors", self.edgeColorCombo.currentText()),
1523                                ])
1524        self.reportSettings("Optimization",
1525                            [("Method", self.optCombo.currentText()),
1526                             ("Iterations", self.frSteps)])
1527        self.reportSection("Graph")
1528        self.reportImage(self.networkCanvas.saveToFileDirect)       
1529       
1530       
1531if __name__=="__main__":   
1532    a=QApplication(sys.argv)
1533    ow=OWNxExplorerQt()
1534    ow.show()
1535    root = 'c:\\Users\\miha\\Projects\\res\\Orange\\test\\'
1536    #net = Orange.network.readwrite.read(root + 'airlines_4.net')
1537    #net.set_items(Orange.data.Table(root + 'airlines_4.tab'))
1538    #net = Orange.network.readwrite.read(root + 'K4K2.net')
1539    net = Orange.network.readwrite.read(root + 'K4K4K5_.net')
1540    ow.set_graph(net)
1541    #ow.handleNewSignals()
1542    #import OWNetExplorer
1543    #ow1=OWNetExplorer.OWNetExplorer()
1544    #ow1.show()
1545    #net1 = Orange.network.Network.read(root + 'K4K4K5_.net')
1546    #ow1.setGraph(net1)
1547    a.exec_()
1548    #save settings
1549    ow.saveSettings()
1550    #ow1.saveSettings()
1551   
1552   
1553   
Note: See TracBrowser for help on using the repository browser.