source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10797:5d99ca1dfb9c

Revision 10797:5d99ca1dfb9c, 74.2 KB checked in by Matija Polajnar <matija.polajnar@…>, 2 years ago (diff)

Bugfix: OWNxExplorer should be nice and not change marking type in an unexpected kind of way ...

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