source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10852:e2f47fdb32b3

Revision 10852:e2f47fdb32b3, 74.2 KB checked in by mstajdohar, 2 years ago (diff)

Fixes #1183.

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                self.networkCanvas.networkCurve.set_node_coordinates(positions)
825
826
827            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
828            self.networkCanvas.maxEdgeSize = self.maxLinkSize
829            self.networkCanvas.minComponentEdgeWidth = self.minComponentEdgeWidth
830            self.networkCanvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
831            self.networkCanvas.set_labels_on_marked(self.labelsOnMarkedOnly)
832
833            self.compute_network_info()
834            self._set_combos()
835
836            lastNameComponentAttributeFound = False
837            for i in range(self.nameComponentCombo.count()):
838                if self.lastNameComponentAttribute == self.nameComponentCombo.itemText(i):
839                    lastNameComponentAttributeFound = True
840                    self.nameComponentAttribute = i
841                    self.nameComponents()
842                    self.showComponentAttribute = self.showComponentCombo.count() - 1
843                    self.showComponents()
844                    break
845
846            if not lastNameComponentAttributeFound:
847                self.lastNameComponentAttribute = ''
848
849            self.showComponentAttribute = None
850
851            t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
852            self.frSteps = int(2.0 / t)
853            if self.frSteps < 1: self.frSteps = 1
854            if self.frSteps > 100: self.frSteps = 100
855
856            # if graph is large, set random layout, min vertex size, min edge size
857            if self.frSteps < 10:
858                self.networkCanvas.update_antialiasing(False)
859                self.networkCanvas.update_animations(False)
860                self.minVertexSize = 5
861                self.maxVertexSize = 5
862                self.maxLinkSize = 1
863                self.optMethod = 0
864                self.graph_layout_method()
865
866            self.networkCanvas.labelsOnMarkedOnly = self.labelsOnMarkedOnly
867            self.networkCanvas.showWeights = self.showWeights
868
869            self.set_node_sizes()
870            self.set_node_colors()
871            self.set_edge_sizes()
872            self.set_edge_colors()
873
874            self._clicked_att_lstbox()
875            self._clicked_tooltip_lstbox()
876            self._clicked_edge_label_listbox()
877
878            self.optButton.setChecked(1)
879            self.graph_layout()
880            self.set_mark_mode()
881
882        def set_network_view(self, nxView):
883            self.error()
884            self.warning()
885            self.information()
886
887            if self.graph is None:
888                self.information('Do not forget to add a graph!')
889
890            if self._network_view is not None:
891                QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
892
893            self._network_view = nxView
894
895            g = self.graph_base
896            if self._network_view is not None:
897                self._network_view.set_nx_explorer(self)
898            else:
899                self.graph_base = None
900
901            self.set_graph(g)
902
903            if self._network_view is not None:
904                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
905
906        def set_items(self, items=None):
907            self.error()
908            self.warning()
909            self.information()
910
911            if items is None:
912                return
913
914            if self.graph is None:
915                self.warning('No graph found!')
916                return
917
918            if len(items) != self.graph_base.number_of_nodes():
919                self.error('Table items must have one example for each node.')
920                return
921
922            self.graph_base.set_items(items)
923
924            self.set_node_sizes()
925            self.networkCanvas.items = items
926            self.networkCanvas.showWeights = self.showWeights
927            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
928            self._set_combos()
929            #self.networkCanvas.updateData()
930
931        def mark_items(self, items):
932            self.markInputCombo.clear()
933            self.markInputRadioButton.setEnabled(False)
934            self.markInputItems = items
935
936            self.error()
937            self.warning()
938            self.information()
939
940            if items is None:
941                return
942
943            if self.graph is None or self.graph_base.items() is None or items is None:
944                self.warning('No graph found or no items attached to the graph.')
945                return
946
947            if len(items) > 0:
948                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()]
949                lstNewDomain = [x.name for x in items.domain] + [items.domain[x].name for x in items.domain.getmetas()]
950                commonVars = set(lstNewDomain) & set(lstOrgDomain)
951
952                self.markInputCombo.addItem(self.icons[Orange.feature.Type.Discrete], unicode("ID"))
953
954                if len(commonVars) > 0:
955                    for var in commonVars:
956                        orgVar = self.graph_base.items().domain[var]
957                        mrkVar = items.domain[var]
958
959                        if orgVar.varType == mrkVar.varType and orgVar.varType == Orange.feature.Type.String:
960                            self.markInputCombo.addItem(self.icons[orgVar.varType], unicode(orgVar.name))
961
962                self.markInputRadioButton.setEnabled(True)
963                self.set_mark_mode(9)
964
965        def set_explore_distances(self):
966            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
967
968            if self.explore_distances:
969                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
970
971        def explore_focused(self):
972            sel = self.networkCanvas.selected_nodes()
973            if len(sel) == 1:
974                ndx_1 = sel[0]
975                self.networkCanvas.label_distances = [['%.2f' % \
976                                self.items_matrix[ndx_1][ndx_2]] \
977                                for ndx_2 in self.networkCanvas.graph.nodes()]
978            else:
979                self.networkCanvas.label_distances = None
980
981            self.networkCanvas.set_node_labels(self.lastLabelColumns)
982            self.networkCanvas.replot()
983
984        #######################################################################
985        ### Layout Optimization                                             ###
986        #######################################################################
987
988        def graph_layout(self):
989            if self.graph is None or self.graph.number_of_nodes <= 0:   #grafa se ni
990                self.optButton.setChecked(False)
991                return
992
993            if not self.optButton.isChecked() and not self.optMethod in [2, 3, 9, 10]:
994                self.optButton.setChecked(False)
995                return
996
997            qApp.processEvents()
998
999            if self.optMethod == 1:
1000                self.networkCanvas.networkCurve.random()
1001            elif self.optMethod == 2:
1002                self.graph_layout_fr(False)
1003            elif self.optMethod == 3:
1004                self.graph_layout_fr(True)
1005            elif self.optMethod == 4:
1006                self.graph_layout_fr_radial()
1007            elif self.optMethod == 5:
1008                self.networkCanvas.networkCurve.circular(\
1009                                            NetworkCurve.circular_crossing)
1010            elif self.optMethod == 6:
1011                self.networkCanvas.networkCurve.circular(\
1012                                            NetworkCurve.circular_original)
1013            elif self.optMethod == 7:
1014                self.networkCanvas.networkCurve.circular(\
1015                                            NetworkCurve.circular_random)
1016            elif self.optMethod == 8:
1017                self.graph_layout_fragviz()
1018            elif self.optMethod == 9:
1019                self.graph_layout_mds()
1020            elif self.optMethod == 10:
1021                self.graph_layout_pivot_mds()
1022
1023            self.optButton.setChecked(False)
1024            self.networkCanvas.update_canvas()
1025
1026        def graph_layout_method(self, method=None):
1027            self.information()
1028            self.stepsSpin.label.setText('Iterations: ')
1029            self.optButton.setEnabled(True)
1030            self.cb_opt_from_curr.setEnabled(False)
1031
1032            if method is not None:
1033                self.optMethod = method
1034
1035            if str(self.optMethod) == '0':
1036                self.optButton.setEnabled(False)
1037            else:
1038                self.optButton.setEnabled(True)
1039
1040            if str(self.optMethod) in ['2', '3', '4']:
1041                self.stepsSpin.setEnabled(True)
1042
1043            elif str(self.optMethod) in ['8', '9', '10']:
1044                if str(self.optMethod) == '8':
1045                    self.stepsSpin.label.setText('Pivots: ')
1046
1047                if str(self.optMethod) in ['9', '10']:
1048                    self.cb_opt_from_curr.setEnabled(True)
1049
1050                self.stepsSpin.setEnabled(True)
1051
1052                if self.items_matrix is None:
1053                    self.information('Set distance matrix to input signal')
1054                    self.optButton.setEnabled(False)
1055                    return
1056                if self.graph is None:
1057                    self.information('No network found')
1058                    self.optButton.setEnabled(False)
1059                    return
1060                if self.items_matrix.dim != self.graph.number_of_nodes():
1061                    self.error('Distance matrix dimensionality must equal number of vertices')
1062                    self.optButton.setEnabled(False)
1063                    return
1064            else:
1065                self.stepsSpin.setEnabled(False)
1066                self.optButton.setChecked(True)
1067                self.graph_layout()
1068
1069        def mds_progress(self, avgStress, stepCount):
1070            #self.drawForce()
1071
1072            #self.mdsInfoA.setText("Avg. Stress: %.20f" % avgStress)
1073            #self.mdsInfoB.setText("Num. steps: %i" % stepCount)
1074            self.progressBarSet(int(stepCount * 100 / self.frSteps))
1075            qApp.processEvents()
1076
1077        def graph_layout_fragviz(self):
1078            if self.items_matrix is None:
1079                self.information('Set distance matrix to input signal')
1080                self.optButton.setChecked(False)
1081                return
1082
1083            if self.layout is None:
1084                self.information('No network found')
1085                self.optButton.setChecked(False)
1086                return
1087
1088            if self.items_matrix.dim != self.graph.number_of_nodes():
1089                self.error('Distance matrix dimensionality must equal number of vertices')
1090                self.optButton.setChecked(False)
1091                return
1092
1093            if not self.optButton.isChecked():
1094                self.networkCanvas.networkCurve.stopMDS = True
1095                self.optButton.setChecked(False)
1096                self.optButton.setText("Optimize layout")
1097                return
1098
1099            self.optButton.setText("Stop")
1100            self.progressBarInit()
1101            qApp.processEvents()
1102
1103            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1104                matrix = self.items_matrix
1105            else:
1106                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1107
1108            self.networkCanvas.networkCurve.layout_fragviz(self.frSteps, matrix, self.graph, self.mds_progress, self.opt_from_curr)
1109
1110            self.optButton.setChecked(False)
1111            self.optButton.setText("Optimize layout")
1112            self.progressBarFinished()
1113
1114        def graph_layout_mds(self):
1115            if self.items_matrix is None:
1116                self.information('Set distance matrix to input signal')
1117                self.optButton.setChecked(False)
1118                return
1119
1120            if self.layout is None:
1121                self.information('No network found')
1122                self.optButton.setChecked(False)
1123                return
1124
1125            if self.items_matrix.dim != self.graph.number_of_nodes():
1126                self.error('Distance matrix dimensionality must equal number of vertices')
1127                self.optButton.setChecked(False)
1128                return
1129
1130            if not self.optButton.isChecked():
1131                self.networkCanvas.networkCurve.stopMDS = True
1132                self.optButton.setChecked(False)
1133                self.optButton.setText("Optimize layout")
1134                return
1135
1136            self.optButton.setText("Stop")
1137            self.progressBarInit()
1138            qApp.processEvents()
1139
1140            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1141                matrix = self.items_matrix
1142            else:
1143                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1144
1145            self.networkCanvas.networkCurve.layout_mds(self.frSteps, matrix, self.mds_progress, self.opt_from_curr)
1146
1147            self.optButton.setChecked(False)
1148            self.optButton.setText("Optimize layout")
1149            self.progressBarFinished()
1150
1151        def graph_layout_fr(self, weighted):
1152            if self.graph is None:
1153                return
1154
1155            if not self.optButton.isChecked():
1156                self.networkCanvas.networkCurve.stop_optimization()
1157                self.optButton.setChecked(False)
1158                self.optButton.setText("Optimize layout")
1159                return
1160
1161            self.optButton.setText("Stop")
1162            qApp.processEvents()
1163            self.networkCanvas.networkCurve.layout_fr(self.frSteps, False)
1164           # self.networkCanvas.update_canvas()
1165            self.optButton.setChecked(False)
1166            self.optButton.setText("Optimize layout")
1167
1168        def graph_layout_fr_radial(self):
1169            if self.graph is None:   #grafa se ni
1170                return
1171
1172    #        #print "F-R Radial"
1173    #        k = 1.13850193174e-008
1174    #        nodes = self.graph.number_of_nodes()
1175    #        t = k * nodes * nodes
1176    #        refreshRate = int(5.0 / t)
1177    #        if refreshRate <    1: refreshRate = 1
1178    #        if refreshRate > 1500: refreshRate = 1500
1179    #        #print "refreshRate: " + str(refreshRate)
1180    #       
1181    #        tolerance = 5
1182    #        initTemp = 100
1183    #        centerNdx = 0
1184    #       
1185    #        selection = self.networkCanvas.getSelection()
1186    #        if len(selection) > 0:
1187    #            centerNdx = selection[0]
1188    #           
1189    #        #print "center ndx: " + str(centerNdx)
1190    #        initTemp = self.layout.fr_radial(centerNdx, refreshRate, initTemp)
1191    #        self.networkCanvas.circles = [10000 / 12, 10000/12*2, 10000/12*3]#, 10000/12*4, 10000/12*5]
1192    #        #self.networkCanvas.circles = [100, 200, 300]
1193    #        self.networkCanvas.updateCanvas()
1194    #        self.networkCanvas.circles = []
1195
1196        def graph_layout_pivot_mds(self):
1197            self.information()
1198
1199            if self.items_matrix is None:
1200                self.information('Set distance matrix to input signal')
1201                return
1202
1203            if self.graph_base is None:
1204                self.information('No network found')
1205                return
1206
1207            if self.items_matrix.dim != self.graph_base.number_of_nodes():
1208                self.error('The number of vertices does not match matrix size.')
1209                return
1210
1211            self.frSteps = min(self.frSteps, self.graph.number_of_nodes())
1212            qApp.processEvents()
1213
1214            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1215                matrix = self.items_matrix
1216            else:
1217                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1218
1219            mds = orngMDS.PivotMDS(matrix, self.frSteps)
1220            x, y = mds.optimize()
1221            xy = zip(list(x), list(y))
1222            coors = dict(zip(sorted(self.graph.nodes()), xy))
1223            self.networkCanvas.networkCurve.set_node_coordinates(coors)
1224            self.networkCanvas.update_canvas()
1225
1226        #######################################################################
1227        ### Network Visualization                                           ###
1228        #######################################################################
1229
1230        def _set_colors(self):
1231            dlg = self._create_color_dialog(self.colorSettings, self.selectedSchemaIndex)
1232            if dlg.exec_():
1233                self.colorSettings = dlg.getColorSchemas()
1234                self.selectedSchemaIndex = dlg.selectedSchemaIndex
1235                self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
1236                self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
1237
1238                self.set_node_colors()
1239
1240        def _set_edge_color_palette(self):
1241            dlg = self._create_color_dialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
1242            if dlg.exec_():
1243                self.edgeColorSettings = dlg.getColorSchemas()
1244                self.selectedEdgeSchemaIndex = dlg.selectedSchemaIndex
1245                self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
1246                self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
1247
1248                self.set_edge_colors()
1249
1250        def _create_color_dialog(self, colorSettings, selectedSchemaIndex):
1251            c = OWColorPalette.ColorPaletteDlg(self, "Color Palette")
1252            c.createDiscretePalette("discPalette", "Discrete Palette")
1253            c.createContinuousPalette("contPalette", "Continuous Palette")
1254            c.setColorSchemas(colorSettings, selectedSchemaIndex)
1255            return c
1256
1257        def _clicked_att_lstbox(self):
1258            if self.graph is None:
1259                return
1260
1261            self.lastLabelColumns = [self.attributes[i][0] for i in self.markerAttributes]
1262            self.networkCanvas.set_node_labels(self.lastLabelColumns)
1263            self.networkCanvas.replot()
1264
1265        def _clicked_tooltip_lstbox(self):
1266            if self.graph is None:
1267                return
1268
1269            self.lastTooltipColumns = [self.attributes[i][0] for i in self.tooltipAttributes]
1270            self.networkCanvas.set_tooltip_attributes(self.lastTooltipColumns)
1271            self.networkCanvas.replot()
1272
1273        def _clicked_edge_label_listbox(self):
1274            if self.graph is None:
1275                return
1276
1277            self.lastEdgeLabelAttributes = set([self.edgeAttributes[i][0] for i in self.edgeLabelAttributes])
1278            self.networkCanvas.set_edge_labels(self.lastEdgeLabelAttributes)
1279            self.networkCanvas.replot()
1280
1281        def set_node_colors(self):
1282            if self.graph is None:
1283                return
1284
1285            self.networkCanvas.set_node_colors(self.colorCombo.currentText())
1286            self.lastColorColumn = self.colorCombo.currentText()
1287
1288        def set_edge_colors(self):
1289            if self.graph is None:
1290                return
1291
1292            self.networkCanvas.set_edge_colors(self.edgeColorCombo.currentText())
1293            self.lastEdgeColorColumn = self.edgeColorCombo.currentText()
1294
1295        def set_edge_sizes(self):
1296            if self.graph is None:
1297                return
1298
1299            self.networkCanvas.networkCurve.set_edge_sizes(self.maxLinkSize)
1300            self.networkCanvas.replot()
1301
1302        def set_node_sizes(self):
1303            if self.graph is None or self.networkCanvas is None:
1304                return
1305
1306            if self.minVertexSize > self.maxVertexSize:
1307                self.maxVertexSize = self.minVertexSize
1308
1309            items = self.graph_base.items()
1310
1311            if items is None:
1312                self.networkCanvas.networkCurve.set_node_sizes({}, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1313                return
1314
1315            self.lastVertexSizeColumn = self.vertexSizeCombo.currentText()
1316            column = str(self.vertexSizeCombo.currentText())
1317
1318            values = {}
1319            if column in items.domain or (column.startswith("num of ") and column.replace("num of ", "") in items.domain):
1320                if column in items.domain:
1321                    values = dict((x, items[x][column].value) for x in self.graph if not items[x][column].isSpecial())
1322                else:
1323                    values = dict((x, len(items[x][column.replace("num of ", "")].value.split(','))) for x in self.graph)
1324
1325            if len(values) == 0:
1326                values = dict((node, 1.) for node in self.graph)
1327
1328            if self.invertSize:
1329                maxval = max(values.itervalues())
1330                values.update((key, maxval - val) for key, val in values.iteritems())
1331                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1332            else:
1333                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1334
1335            self.networkCanvas.replot()
1336
1337        def set_font(self):
1338            if self.networkCanvas is None:
1339                return
1340
1341            weights = {0: 50, 1: 80}
1342
1343            font = self.networkCanvas.font()
1344            font.setPointSize(self.fontSize)
1345            font.setWeight(weights[self.fontWeight])
1346            self.networkCanvas.setFont(font)
1347            self.networkCanvas.fontSize = font
1348            self.networkCanvas.set_node_labels()
1349
1350        def sendReport(self):
1351            self.reportSettings("Graph data",
1352                                [("Number of vertices", self.graph.number_of_nodes()),
1353                                 ("Number of edges", self.graph.number_of_edges()),
1354                                 ("Vertices per edge", "%.3f" % self.verticesPerEdge),
1355                                 ("Edges per vertex", "%.3f" % self.edgesPerVertex),
1356                                 ])
1357            if self.color or self.vertexSize or self.markerAttributes or self.edgeColor:
1358                self.reportSettings("Visual settings",
1359                                    [self.color and ("Vertex color", self.colorCombo.currentText()),
1360                                     self.vertexSize and ("Vertex size", str(self.vertexSizeCombo.currentText()) + " (inverted)" if self.invertSize else ""),
1361                                     self.markerAttributes and ("Labels", ", ".join(self.attributes[i][0] for i in self.markerAttributes)),
1362                                     self.edgeColor and ("Edge colors", self.edgeColorCombo.currentText()),
1363                                    ])
1364            self.reportSettings("Optimization",
1365                                [("Method", self.optCombo.currentText()),
1366                                 ("Iterations", self.frSteps)])
1367            self.reportSection("Graph")
1368            self.reportImage(self.networkCanvas.saveToFileDirect)
1369
1370        #######################################################################
1371        ### PROTOTYPE                                                       ###
1372        #######################################################################
1373
1374        def set_component_edge_width(self, changedMin=True):
1375            if self.networkCanvas is None:
1376                return
1377
1378            canvas = self.networkCanvas
1379            if changedMin:
1380                if self.maxComponentEdgeWidth < self.minComponentEdgeWidth:
1381                    self.maxComponentEdgeWidth = self.minComponentEdgeWidth
1382            else:
1383                if self.minComponentEdgeWidth > self.maxComponentEdgeWidth:
1384                    self.minComponentEdgeWidth = self.maxComponentEdgeWidth
1385
1386            canvas.minComponentEdgeWidth = self.minComponentEdgeWidth
1387            canvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
1388            self.networkCanvas.updateCanvas()
1389
1390        def showComponents(self):
1391            if self.graph is None or self.graph_base.items() is None:
1392                return
1393
1394            vars = [x.name for x in self.graph_base.items_vars()]
1395
1396            if not self.showComponentCombo.currentText() in vars:
1397                self.networkCanvas.showComponentAttribute = None
1398                self.lastNameComponentAttribute = ''
1399            else:
1400                self.networkCanvas.showComponentAttribute = self.showComponentCombo.currentText()
1401
1402            self.networkCanvas.drawComponentKeywords()
1403
1404        def nameComponents(self):
1405            """Names connected components of genes according to GO terms."""
1406            self.progressBarFinished()
1407            self.lastNameComponentAttribute = None
1408
1409            if self.graph is None or self.graph_base.items() is None:
1410                return
1411
1412            vars = [x.name for x in self.graph_base.items_vars()]
1413            if not self.nameComponentCombo.currentText() in vars:
1414                return
1415
1416            self.progressBarInit()
1417            components = [c for c in Orange.network.nx.algorithms.components.connected_components(self.graph) if len(c) > 1]
1418            if 'component name' in self.graph_base.items().domain:
1419                keyword_table = self.graph_base.items()
1420            else:
1421                keyword_table = Orange.data.Table(Orange.data.Domain(Orange.feature.String('component name')), [[''] for i in range(len(self.graph_base.items()))])
1422
1423            import obiGO
1424            ontology = obiGO.Ontology.Load(progressCallback=self.progressBarSet)
1425            annotations = obiGO.Annotations.Load(self.organism, ontology=ontology, progressCallback=self.progressBarSet)
1426
1427            allGenes = set([e[str(self.nameComponentCombo.currentText())].value for e in self.graph_base.items()])
1428            foundGenesets = False
1429            if len(annotations.geneNames & allGenes) < 1:
1430                allGenes = set(reduce(operator.add, [e[str(self.nameComponentCombo.currentText())].value.split(', ') for e in self.graph_base.items()]))
1431                if len(annotations.geneNames & allGenes) < 1:
1432                    self.warning('no genes found')
1433                    return
1434                else:
1435                    foundGenesets = True
1436
1437            def rank(a, j, reverse=False):
1438                if len(a) <= 0: return
1439
1440                if reverse:
1441                    a.sort(lambda x, y: 1 if x[j] > y[j] else -1 if x[j] < y[j] else 0)
1442                    top_value = a[0][j]
1443                    top_rank = len(a)
1444                    max_rank = float(len(a))
1445                    int_ndx = 0
1446                    for k in range(len(a)):
1447                        if top_value < a[k][j]:
1448                            top_value = a[k][j]
1449                            if k - int_ndx > 1:
1450                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1451                                for l in range(int_ndx, k):
1452                                    a[l][j] = avg_rank
1453
1454                            int_ndx = k
1455
1456                        a[k][j] = top_rank / max_rank
1457                        top_rank -= 1
1458
1459                    k += 1
1460                    if k - int_ndx > 1:
1461                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1462                        for l in range(int_ndx, k):
1463                            a[l][j] = avg_rank
1464
1465                else:
1466                    a.sort(lambda x, y: 1 if x[j] < y[j] else -1 if x[j] > y[j] else 0)
1467                    top_value = a[0][j]
1468                    top_rank = len(a)
1469                    max_rank = float(len(a))
1470                    int_ndx = 0
1471                    for k in range(len(a)):
1472                        if top_value > a[k][j]:
1473                            top_value = a[k][j]
1474                            if k - int_ndx > 1:
1475                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1476                                for l in range(int_ndx, k):
1477                                    a[l][j] = avg_rank
1478
1479                            int_ndx = k
1480
1481                        a[k][j] = top_rank / max_rank
1482                        top_rank -= 1
1483
1484                    k += 1
1485                    if k - int_ndx > 1:
1486                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1487                        for l in range(int_ndx, k):
1488                            a[l][j] = avg_rank
1489
1490            for i in range(len(components)):
1491                component = components[i]
1492                if len(component) <= 1:
1493                    continue
1494
1495                if foundGenesets:
1496                    genes = reduce(operator.add, [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value.split(', ') for v in component])
1497                else:
1498                    genes = [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value for v in component]
1499
1500                res1 = annotations.GetEnrichedTerms(genes, aspect="P")
1501                res2 = annotations.GetEnrichedTerms(genes, aspect="F")
1502                res = res1.items() + res2.items()
1503                #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]
1504                #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]
1505
1506                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]
1507                if len(namingScore) == 0:
1508                    continue
1509
1510                annotated_genes = max([a[0] for a in namingScore])
1511
1512                rank(namingScore, 1, reverse=True)
1513                rank(namingScore, 2, reverse=True)
1514                rank(namingScore, 0)
1515
1516                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]
1517                namingScore.sort(reverse=True)
1518
1519                if len(namingScore) < 1:
1520                    print "warning. no annotations found for group of genes: " + ", ".join(genes)
1521                    continue
1522                elif len(namingScore[0]) < 2:
1523                    print "warning. error computing score for group of genes: " + ", ".join(genes)
1524                    continue
1525
1526                for v in component:
1527                    name = str(namingScore[0][1])
1528                    attrs = "%d/%d, %d, %lf" % (namingScore[0][2], annotated_genes, namingScore[0][3], namingScore[0][4])
1529                    info = ''
1530                    if self.showTextMiningInfo:
1531                        info = "\n" + attrs + "\n" + str(namingScore[0][0])
1532                    keyword_table[v]['component name'] = name + info
1533
1534                self.progressBarSet(i * 100.0 / len(components))
1535
1536            self.lastNameComponentAttribute = self.nameComponentCombo.currentText()
1537            self.set_items(Orange.data.Table([self.graph_base.items(), keyword_table]))
1538            self.progressBarFinished()
1539
1540
1541        def setAutoSendAttributes(self):
1542            print 'TODO setAutoSendAttributes'
1543            #if self.autoSendAttributes:
1544            #    self.networkCanvas.callbackSelectVertex = self.sendAttSelectionList
1545            #else:
1546            #    self.networkCanvas.callbackSelectVertex = None
1547
1548        def sendAttSelectionList(self):
1549            if not self.graph is None:
1550                vars = [x.name for x in self.graph_base.links_vars()]
1551                if not self.comboAttSelection.currentText() in vars:
1552                    return
1553                att = str(self.comboAttSelection.currentText())
1554                vertices = self.networkCanvas.selected_nodes()
1555
1556                if len(vertices) != 1:
1557                    return
1558
1559                attributes = str(self.graph_base.items()[vertices[0]][att]).split(', ')
1560            else:
1561                attributes = None
1562            self.send("Features", attributes)
1563
1564
1565except ImportError as err:
1566    try:
1567        from OWNxCanvas import *
1568    except:
1569        # if Qwt is also not installed throw could not import orangeqt error
1570        raise err
1571
1572    from OWNxExplorerQwt import OWNxExplorerQwt as OWNxExplorer
1573
1574if __name__ == "__main__":
1575    a = QApplication(sys.argv)
1576    ow = OWNxExplorer()
1577    ow.show()
1578
1579    def setNetwork(signal, data, id=None):
1580        if signal == 'Network':
1581            ow.set_graph(data)
1582        #if signal == 'Items':
1583        #    ow.set_items(data)
1584
1585    import OWNxFile
1586    owFile = OWNxFile.OWNxFile()
1587    owFile.send = setNetwork
1588    owFile.show()
1589    owFile.selectNetFile(0)
1590
1591    a.exec_()
1592    ow.saveSettings()
1593    owFile.saveSettings()
Note: See TracBrowser for help on using the repository browser.