source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10796:6516880fb239

Revision 10796:6516880fb239, 74.1 KB checked in by Matija Polajnar <matija.polajnar@…>, 2 years ago (diff)

Bugfix: OWNxExplorer showed incorrect number of selected nodes (always 0).

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