source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10861:5f70ff13ecc2

Revision 10861:5f70ff13ecc2, 74.3 KB checked in by mstajdohar, 2 years ago (diff)

Fixed some bugs on directed graph.

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