source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10734:7bcd7e8a0d75

Revision 10734:7bcd7e8a0d75, 74.0 KB checked in by mstajdohar, 2 years ago (diff)

BUG: fixed on remove net_view.

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            if len(self.signalManager.getLinks(self, None, \
557                "Selected Items", None)) > 0 or \
558                    len(self.signalManager.getLinks(self, None, \
559                        "Unselected Items", None)) > 0 or \
560                            len(self.signalManager.getLinks(self, None, \
561                                "Selected Network", None)) > 0:
562
563                # signal connected
564                selected_nodes = self.networkCanvas.selected_nodes()
565                graph = self.graph_base.subgraph(selected_nodes)
566
567                if graph is not None:
568                    self.send("Selected Items", graph.items())
569
570                    if len(self.signalManager.getLinks(self, None, \
571                                                "Unselected Items", None)) > 0:
572                        nodes = self.networkCanvas.not_selected_nodes()
573                        if len(nodes) > 0 and self.graph_base.items() is not None:
574                            self.send("Other Items", self.graph_base.items().getitems(nodes))
575                        else:
576                            self.send("Other Items", None)
577
578                    self.send("Selected Network", graph)
579                else:
580                    self.send("Selected Items", None)
581                    self.send("Other Items", None)
582                    self.send("Selected Network", None)
583
584            if len(self.signalManager.getLinks(self, None, \
585                                "Selected Items Distance Matrix", None)) > 0:
586                # signal connected
587                matrix = None if self.items_matrix is None else self.items_matrix.getitems(selected_nodes)
588                self.send("Distance Matrix", matrix)
589
590        def send_marked_nodes(self):
591            if self.checkSendMarkedNodes and \
592                len(self.signalManager.getLinks(self, None, \
593                                                "Marked Items", None)) > 0:
594                # signal connected
595                markedNodes = self.networkCanvas.marked_nodes()
596
597                if len(markedNodes) > 0 and self.graph is not None and\
598                                         self.graph_base.items() is not None:
599
600                    items = self.graph_base.items().getitems(markedNodes)
601                    self.send("Marked Items", items)
602                else:
603                    self.send("Marked Items", None)
604
605        def _set_combos(self):
606            vars = self.graph_base.items_vars()
607            edgeVars = self.graph_base.links_vars()
608            lastLabelColumns = self.lastLabelColumns
609            lastTooltipColumns = self.lastTooltipColumns
610
611            self._clear_combos()
612
613            self.attributes = [(var.name, var.varType) for var in vars]
614            self.edgeAttributes = [(var.name, var.varType) for var in edgeVars]
615
616            for var in vars:
617                if var.varType in [Orange.feature.Type.Discrete, \
618                                   Orange.feature.Type.Continuous]:
619                    self.colorCombo.addItem(self.icons.get(var.varType, \
620                                            self.icons[-1]), unicode(var.name))
621
622                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:
623
624                    value = self.graph_base.items()[0][var].value
625
626                    # can value be a list?
627                    try:
628                        if type(eval(value)) == type([]):
629                            self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
630                            continue
631                    except:
632                        pass
633
634                    if len(value.split(',')) > 1:
635                        self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), "num of " + unicode(var.name))
636
637                elif var.varType in [Orange.feature.Type.Continuous]:
638                    self.vertexSizeCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
639
640                self.nameComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
641                self.showComponentCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
642                self.editCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
643                self.comboAttSelection.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
644
645            for var in edgeVars:
646                if var.varType in [Orange.feature.Type.Discrete, Orange.feature.Type.Continuous]:
647                    self.edgeColorCombo.addItem(self.icons.get(var.varType, self.icons[-1]), unicode(var.name))
648
649            for i in range(self.vertexSizeCombo.count()):
650                if self.lastVertexSizeColumn == \
651                        self.vertexSizeCombo.itemText(i):
652                    self.vertexSize = i
653                    self.set_node_sizes()
654                    break
655
656            for i in range(self.colorCombo.count()):
657                if self.lastColorColumn == self.colorCombo.itemText(i):
658                    self.color = i
659                    self.set_node_colors()
660                    break
661
662            for i in range(self.attListBox.count()):
663                if str(self.attListBox.item(i).text()) in lastLabelColumns:
664                    self.attListBox.item(i).setSelected(1)
665                self._clicked_att_lstbox()
666
667            for i in range(self.tooltipListBox.count()):
668                if str(self.tooltipListBox.item(i).text()) \
669                                                    in lastTooltipColumns:
670                    self.tooltipListBox.item(i).setSelected(1)
671                self._clicked_tooltip_lstbox()
672
673            self.lastLabelColumns = lastLabelColumns
674            self.lastTooltipColumns = lastTooltipColumns
675
676        def _clear_combos(self):
677            self.attributes = []
678            self.edgeAttributes = []
679
680            self.colorCombo.clear()
681            self.vertexSizeCombo.clear()
682            self.nameComponentCombo.clear()
683            self.showComponentCombo.clear()
684            self.edgeColorCombo.clear()
685            self.editCombo.clear()
686            self.comboAttSelection.clear()
687
688            self.colorCombo.addItem("(same color)")
689            self.edgeColorCombo.addItem("(same color)")
690            self.vertexSizeCombo.addItem("(same size)")
691            self.nameComponentCombo.addItem("Select attribute")
692            self.showComponentCombo.addItem("Select attribute")
693            self.editCombo.addItem("Select attribute")
694            self.comboAttSelection.addItem("Select attribute")
695
696        def compute_network_info(self):
697            self.nShown = self.graph.number_of_nodes()
698
699            if self.graph.number_of_edges() > 0:
700                self.verticesPerEdge = float(self.graph.number_of_nodes()) / float(self.graph.number_of_edges())
701            else:
702                self.verticesPerEdge = 0
703
704            if self.graph.number_of_nodes() > 0:
705                self.edgesPerVertex = float(self.graph.number_of_edges()) / float(self.graph.number_of_nodes())
706            else:
707                self.edgesPerVertex = 0
708
709        def change_graph(self, newgraph):
710            self.information()
711
712            # if graph has more nodes and edges than pixels in 1600x1200 display,
713            # it is too big to visualize!
714            if newgraph.number_of_nodes() + newgraph.number_of_edges() > 50000:
715                self.information('New graph is too big to visualize. Keeping the old graph.')
716                return
717
718            self.graph = newgraph
719
720            self.number_of_nodes_label = self.graph.number_of_nodes()
721            self.number_of_edges_label = self.graph.number_of_edges()
722
723            if not self.networkCanvas.change_graph(self.graph):
724                return
725
726            self.compute_network_info()
727
728            if self.graph.number_of_nodes() > 0:
729                t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
730                self.frSteps = int(2.0 / t)
731                if self.frSteps < 1: self.frSteps = 1
732                if self.frSteps > 100: self.frSteps = 100
733    #       
734    #        if self.frSteps < 10:
735    #            self.networkCanvas.use_antialiasing = 0
736    #            self.networkCanvas.use_animations = 0
737    #            self.minVertexSize = 5
738    #            self.maxVertexSize = 5
739    #            self.maxLinkSize = 1
740    #            self.optMethod = 0
741    #            self.graph_layout_method()
742
743            animation_enabled = self.networkCanvas.animate_points;
744            self.networkCanvas.animate_points = False;
745
746            self.set_node_sizes()
747            self.set_node_colors()
748            self.set_edge_sizes()
749            self.set_edge_colors()
750
751            self._clicked_att_lstbox()
752            self._clicked_tooltip_lstbox()
753            self._clicked_edge_label_listbox()
754
755            self.networkCanvas.replot()
756
757            self.networkCanvas.animate_points = animation_enabled
758            qApp.processEvents()
759            self.networkCanvas.networkCurve.layout_fr(100, weighted=False, smooth_cooling=True)
760            self.networkCanvas.update_canvas()
761
762        def set_graph_none(self):
763            self.graph = None
764            #self.graph_base = None
765            self._clear_combos()
766            self.number_of_nodes_label = -1
767            self.number_of_edges_label = -1
768            self._items = None
769            self._links = None
770            self.set_items_distance_matrix(None)
771            self.networkCanvas.set_graph(None)
772
773        def set_graph(self, graph, curve=None):
774            self.information()
775            self.warning()
776            self.error()
777
778            if graph is None:
779                self.set_graph_none()
780                return
781
782            if graph.number_of_nodes() < 2:
783                self.set_graph_none()
784                self.information('I\'m not really in a mood to visualize just one node. Try again tomorrow.')
785                return
786
787            if graph == self.graph_base and self.graph is not None and \
788                                                    self._network_view is None:
789                self.set_items(graph.items())
790                return
791
792            self.graph_base = graph
793
794            if self._network_view is not None:
795                graph = self._network_view.init_network(graph)
796
797            self.graph = graph
798
799            # if graph has more nodes and edges than pixels in 1600x1200 display,
800            # it is too big to visualize!
801            if self.graph.number_of_nodes() + self.graph.number_of_edges() > 50000:
802                self.set_graph_none()
803                self.error('Graph is too big to visualize. Try using one of the network views.')
804                return
805
806            if self.items_matrix is not None and self.items_matrix.dim != self.graph_base.number_of_nodes():
807                self.set_items_distance_matrix(None)
808
809            self.number_of_nodes_label = self.graph.number_of_nodes()
810            self.number_of_edges_label = self.graph.number_of_edges()
811
812            self.networkCanvas.set_graph(self.graph, curve, items=self.graph_base.items(), links=self.graph_base.links())
813
814            if self._items is not None and 'x' in self._items.domain and 'y' in self._items.domain:
815                positions = dict((node, (self._items[node]['x'].value, self._items[node]['y'].value)) \
816                             for node in self.graph if self._items[node]['x'].value != '?' \
817                             and self._items[node]['y'].value != '?')
818
819                self.networkCanvas.networkCurve.set_node_coordinates(positions)
820
821
822            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
823            self.networkCanvas.maxEdgeSize = self.maxLinkSize
824            self.networkCanvas.minComponentEdgeWidth = self.minComponentEdgeWidth
825            self.networkCanvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
826            self.networkCanvas.set_labels_on_marked(self.labelsOnMarkedOnly)
827
828            self.compute_network_info()
829            self._set_combos()
830
831            lastNameComponentAttributeFound = False
832            for i in range(self.nameComponentCombo.count()):
833                if self.lastNameComponentAttribute == self.nameComponentCombo.itemText(i):
834                    lastNameComponentAttributeFound = True
835                    self.nameComponentAttribute = i
836                    self.nameComponents()
837                    self.showComponentAttribute = self.showComponentCombo.count() - 1
838                    self.showComponents()
839                    break
840
841            if not lastNameComponentAttributeFound:
842                self.lastNameComponentAttribute = ''
843
844            self.showComponentAttribute = None
845
846            t = 1.13850193174e-008 * (self.graph.number_of_nodes() ** 2 + self.graph.number_of_edges())
847            self.frSteps = int(2.0 / t)
848            if self.frSteps < 1: self.frSteps = 1
849            if self.frSteps > 100: self.frSteps = 100
850
851            # if graph is large, set random layout, min vertex size, min edge size
852            if self.frSteps < 10:
853                self.networkCanvas.update_antialiasing(False)
854                self.networkCanvas.update_animations(False)
855                self.minVertexSize = 5
856                self.maxVertexSize = 5
857                self.maxLinkSize = 1
858                self.optMethod = 0
859                self.graph_layout_method()
860
861            self.networkCanvas.labelsOnMarkedOnly = self.labelsOnMarkedOnly
862            self.networkCanvas.showWeights = self.showWeights
863
864            self.set_node_sizes()
865            self.set_node_colors()
866            self.set_edge_sizes()
867            self.set_edge_colors()
868
869            self._clicked_att_lstbox()
870            self._clicked_tooltip_lstbox()
871            self._clicked_edge_label_listbox()
872
873            self.optButton.setChecked(1)
874            self.graph_layout()
875            self.set_mark_mode()
876
877        def set_network_view(self, nxView):
878            self.error()
879            self.warning()
880            self.information()
881
882            if self.graph is None:
883                self.information('Do not forget to add a graph!')
884
885            if self._network_view is not None:
886                QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
887
888            self._network_view = nxView
889
890            g = self.graph_base
891            if self._network_view is not None:
892                self._network_view.set_nx_explorer(self)
893            else:
894                self.graph_base = None
895
896            self.set_graph(g)
897
898            if self._network_view is not None:
899                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self._network_view.node_selection_changed)
900
901        def set_items(self, items=None):
902            self.error()
903            self.warning()
904            self.information()
905
906            if items is None:
907                return
908
909            if self.graph is None:
910                self.warning('No graph found!')
911                return
912
913            if len(items) != self.graph_base.number_of_nodes():
914                self.error('Table items must have one example for each node.')
915                return
916
917            self.graph_base.set_items(items)
918
919            self.set_node_sizes()
920            self.networkCanvas.items = items
921            self.networkCanvas.showWeights = self.showWeights
922            self.networkCanvas.showEdgeLabels = self.showEdgeLabels
923            self._set_combos()
924            #self.networkCanvas.updateData()
925
926        def mark_items(self, items):
927            self.markInputCombo.clear()
928            self.markInputRadioButton.setEnabled(False)
929            self.markInputItems = items
930
931            self.error()
932            self.warning()
933            self.information()
934
935            if items is None:
936                return
937
938            if self.graph is None or self.graph_base.items() is None or items is None:
939                self.warning('No graph found or no items attached to the graph.')
940                return
941
942            if len(items) > 0:
943                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()]
944                lstNewDomain = [x.name for x in items.domain] + [items.domain[x].name for x in items.domain.getmetas()]
945                commonVars = set(lstNewDomain) & set(lstOrgDomain)
946
947                self.markInputCombo.addItem(self.icons[Orange.feature.Type.Discrete], unicode("ID"))
948
949                if len(commonVars) > 0:
950                    for var in commonVars:
951                        orgVar = self.graph_base.items().domain[var]
952                        mrkVar = items.domain[var]
953
954                        if orgVar.varType == mrkVar.varType and orgVar.varType == Orange.feature.Type.String:
955                            self.markInputCombo.addItem(self.icons[orgVar.varType], unicode(orgVar.name))
956
957                self.markInputRadioButton.setEnabled(True)
958                self.set_mark_mode(9)
959
960        def set_explore_distances(self):
961            QObject.disconnect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
962
963            if self.explore_distances:
964                QObject.connect(self.networkCanvas, SIGNAL('selection_changed()'), self.explore_focused)
965
966        def explore_focused(self):
967            sel = self.networkCanvas.selected_nodes()
968            if len(sel) == 1:
969                ndx_1 = sel[0]
970                self.networkCanvas.label_distances = [['%.2f' % \
971                                self.items_matrix[ndx_1][ndx_2]] \
972                                for ndx_2 in self.networkCanvas.graph.nodes()]
973            else:
974                self.networkCanvas.label_distances = None
975
976            self.networkCanvas.set_node_labels(self.lastLabelColumns)
977            self.networkCanvas.replot()
978
979        #######################################################################
980        ### Layout Optimization                                             ###
981        #######################################################################
982
983        def graph_layout(self):
984            if self.graph is None or self.graph.number_of_nodes <= 0:   #grafa se ni
985                self.optButton.setChecked(False)
986                return
987
988            if not self.optButton.isChecked() and not self.optMethod in [2, 3, 9, 10]:
989                self.optButton.setChecked(False)
990                return
991
992            qApp.processEvents()
993
994            if self.optMethod == 1:
995                self.networkCanvas.networkCurve.random()
996            elif self.optMethod == 2:
997                self.graph_layout_fr(False)
998            elif self.optMethod == 3:
999                self.graph_layout_fr(True)
1000            elif self.optMethod == 4:
1001                self.graph_layout_fr_radial()
1002            elif self.optMethod == 5:
1003                self.networkCanvas.networkCurve.circular(\
1004                                            NetworkCurve.circular_crossing)
1005            elif self.optMethod == 6:
1006                self.networkCanvas.networkCurve.circular(\
1007                                            NetworkCurve.circular_original)
1008            elif self.optMethod == 7:
1009                self.networkCanvas.networkCurve.circular(\
1010                                            NetworkCurve.circular_random)
1011            elif self.optMethod == 8:
1012                self.graph_layout_fragviz()
1013            elif self.optMethod == 9:
1014                self.graph_layout_mds()
1015            elif self.optMethod == 10:
1016                self.graph_layout_pivot_mds()
1017
1018            self.optButton.setChecked(False)
1019            self.networkCanvas.update_canvas()
1020
1021        def graph_layout_method(self, method=None):
1022            self.information()
1023            self.stepsSpin.label.setText('Iterations: ')
1024            self.optButton.setEnabled(True)
1025            self.cb_opt_from_curr.setEnabled(False)
1026
1027            if method is not None:
1028                self.optMethod = method
1029
1030            if str(self.optMethod) == '0':
1031                self.optButton.setEnabled(False)
1032            else:
1033                self.optButton.setEnabled(True)
1034
1035            if str(self.optMethod) in ['2', '3', '4']:
1036                self.stepsSpin.setEnabled(True)
1037
1038            elif str(self.optMethod) in ['8', '9', '10']:
1039                if str(self.optMethod) == '8':
1040                    self.stepsSpin.label.setText('Pivots: ')
1041
1042                if str(self.optMethod) in ['9', '10']:
1043                    self.cb_opt_from_curr.setEnabled(True)
1044
1045                self.stepsSpin.setEnabled(True)
1046
1047                if self.items_matrix is None:
1048                    self.information('Set distance matrix to input signal')
1049                    self.optButton.setEnabled(False)
1050                    return
1051                if self.graph is None:
1052                    self.information('No network found')
1053                    self.optButton.setEnabled(False)
1054                    return
1055                if self.items_matrix.dim != self.graph.number_of_nodes():
1056                    self.error('Distance matrix dimensionality must equal number of vertices')
1057                    self.optButton.setEnabled(False)
1058                    return
1059            else:
1060                self.stepsSpin.setEnabled(False)
1061                self.optButton.setChecked(True)
1062                self.graph_layout()
1063
1064        def mds_progress(self, avgStress, stepCount):
1065            #self.drawForce()
1066
1067            #self.mdsInfoA.setText("Avg. Stress: %.20f" % avgStress)
1068            #self.mdsInfoB.setText("Num. steps: %i" % stepCount)
1069            self.progressBarSet(int(stepCount * 100 / self.frSteps))
1070            qApp.processEvents()
1071
1072        def graph_layout_fragviz(self):
1073            if self.items_matrix is None:
1074                self.information('Set distance matrix to input signal')
1075                self.optButton.setChecked(False)
1076                return
1077
1078            if self.layout is None:
1079                self.information('No network found')
1080                self.optButton.setChecked(False)
1081                return
1082
1083            if self.items_matrix.dim != self.graph.number_of_nodes():
1084                self.error('Distance matrix dimensionality must equal number of vertices')
1085                self.optButton.setChecked(False)
1086                return
1087
1088            if not self.optButton.isChecked():
1089                self.networkCanvas.networkCurve.stopMDS = True
1090                self.optButton.setChecked(False)
1091                self.optButton.setText("Optimize layout")
1092                return
1093
1094            self.optButton.setText("Stop")
1095            self.progressBarInit()
1096            qApp.processEvents()
1097
1098            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1099                matrix = self.items_matrix
1100            else:
1101                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1102
1103            self.networkCanvas.networkCurve.layout_fragviz(self.frSteps, matrix, self.graph, self.mds_progress, self.opt_from_curr)
1104
1105            self.optButton.setChecked(False)
1106            self.optButton.setText("Optimize layout")
1107            self.progressBarFinished()
1108
1109        def graph_layout_mds(self):
1110            if self.items_matrix is None:
1111                self.information('Set distance matrix to input signal')
1112                self.optButton.setChecked(False)
1113                return
1114
1115            if self.layout is None:
1116                self.information('No network found')
1117                self.optButton.setChecked(False)
1118                return
1119
1120            if self.items_matrix.dim != self.graph.number_of_nodes():
1121                self.error('Distance matrix dimensionality must equal number of vertices')
1122                self.optButton.setChecked(False)
1123                return
1124
1125            if not self.optButton.isChecked():
1126                self.networkCanvas.networkCurve.stopMDS = True
1127                self.optButton.setChecked(False)
1128                self.optButton.setText("Optimize layout")
1129                return
1130
1131            self.optButton.setText("Stop")
1132            self.progressBarInit()
1133            qApp.processEvents()
1134
1135            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1136                matrix = self.items_matrix
1137            else:
1138                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1139
1140            self.networkCanvas.networkCurve.layout_mds(self.frSteps, matrix, self.mds_progress, self.opt_from_curr)
1141
1142            self.optButton.setChecked(False)
1143            self.optButton.setText("Optimize layout")
1144            self.progressBarFinished()
1145
1146        def graph_layout_fr(self, weighted):
1147            if self.graph is None:
1148                return
1149
1150            if not self.optButton.isChecked():
1151                self.networkCanvas.networkCurve.stop_optimization()
1152                self.optButton.setChecked(False)
1153                self.optButton.setText("Optimize layout")
1154                return
1155
1156            self.optButton.setText("Stop")
1157            qApp.processEvents()
1158            self.networkCanvas.networkCurve.layout_fr(self.frSteps, False)
1159           # self.networkCanvas.update_canvas()
1160            self.optButton.setChecked(False)
1161            self.optButton.setText("Optimize layout")
1162
1163        def graph_layout_fr_radial(self):
1164            if self.graph is None:   #grafa se ni
1165                return
1166
1167    #        #print "F-R Radial"
1168    #        k = 1.13850193174e-008
1169    #        nodes = self.graph.number_of_nodes()
1170    #        t = k * nodes * nodes
1171    #        refreshRate = int(5.0 / t)
1172    #        if refreshRate <    1: refreshRate = 1
1173    #        if refreshRate > 1500: refreshRate = 1500
1174    #        #print "refreshRate: " + str(refreshRate)
1175    #       
1176    #        tolerance = 5
1177    #        initTemp = 100
1178    #        centerNdx = 0
1179    #       
1180    #        selection = self.networkCanvas.getSelection()
1181    #        if len(selection) > 0:
1182    #            centerNdx = selection[0]
1183    #           
1184    #        #print "center ndx: " + str(centerNdx)
1185    #        initTemp = self.layout.fr_radial(centerNdx, refreshRate, initTemp)
1186    #        self.networkCanvas.circles = [10000 / 12, 10000/12*2, 10000/12*3]#, 10000/12*4, 10000/12*5]
1187    #        #self.networkCanvas.circles = [100, 200, 300]
1188    #        self.networkCanvas.updateCanvas()
1189    #        self.networkCanvas.circles = []
1190
1191        def graph_layout_pivot_mds(self):
1192            self.information()
1193
1194            if self.items_matrix is None:
1195                self.information('Set distance matrix to input signal')
1196                return
1197
1198            if self.graph_base is None:
1199                self.information('No network found')
1200                return
1201
1202            if self.items_matrix.dim != self.graph_base.number_of_nodes():
1203                self.error('The number of vertices does not match matrix size.')
1204                return
1205
1206            self.frSteps = min(self.frSteps, self.graph.number_of_nodes())
1207            qApp.processEvents()
1208
1209            if self.graph.number_of_nodes() == self.graph_base.number_of_nodes():
1210                matrix = self.items_matrix
1211            else:
1212                matrix = self.items_matrix.get_items(sorted(self.graph.nodes()))
1213
1214            mds = orngMDS.PivotMDS(matrix, self.frSteps)
1215            x, y = mds.optimize()
1216            xy = zip(list(x), list(y))
1217            coors = dict(zip(sorted(self.graph.nodes()), xy))
1218            self.networkCanvas.networkCurve.set_node_coordinates(coors)
1219            self.networkCanvas.update_canvas()
1220
1221        #######################################################################
1222        ### Network Visualization                                           ###
1223        #######################################################################
1224
1225        def _set_colors(self):
1226            dlg = self._create_color_dialog(self.colorSettings, self.selectedSchemaIndex)
1227            if dlg.exec_():
1228                self.colorSettings = dlg.getColorSchemas()
1229                self.selectedSchemaIndex = dlg.selectedSchemaIndex
1230                self.networkCanvas.contPalette = dlg.getContinuousPalette("contPalette")
1231                self.networkCanvas.discPalette = dlg.getDiscretePalette("discPalette")
1232
1233                self.set_node_colors()
1234
1235        def _set_edge_color_palette(self):
1236            dlg = self._create_color_dialog(self.edgeColorSettings, self.selectedEdgeSchemaIndex)
1237            if dlg.exec_():
1238                self.edgeColorSettings = dlg.getColorSchemas()
1239                self.selectedEdgeSchemaIndex = dlg.selectedSchemaIndex
1240                self.networkCanvas.contEdgePalette = dlg.getContinuousPalette("contPalette")
1241                self.networkCanvas.discEdgePalette = dlg.getDiscretePalette("discPalette")
1242
1243                self.set_edge_colors()
1244
1245        def _create_color_dialog(self, colorSettings, selectedSchemaIndex):
1246            c = OWColorPalette.ColorPaletteDlg(self, "Color Palette")
1247            c.createDiscretePalette("discPalette", "Discrete Palette")
1248            c.createContinuousPalette("contPalette", "Continuous Palette")
1249            c.setColorSchemas(colorSettings, selectedSchemaIndex)
1250            return c
1251
1252        def _clicked_att_lstbox(self):
1253            if self.graph is None:
1254                return
1255
1256            self.lastLabelColumns = [self.attributes[i][0] for i in self.markerAttributes]
1257            self.networkCanvas.set_node_labels(self.lastLabelColumns)
1258            self.networkCanvas.replot()
1259
1260        def _clicked_tooltip_lstbox(self):
1261            if self.graph is None:
1262                return
1263
1264            self.lastTooltipColumns = [self.attributes[i][0] for i in self.tooltipAttributes]
1265            self.networkCanvas.set_tooltip_attributes(self.lastTooltipColumns)
1266            self.networkCanvas.replot()
1267
1268        def _clicked_edge_label_listbox(self):
1269            if self.graph is None:
1270                return
1271
1272            self.lastEdgeLabelAttributes = set([self.edgeAttributes[i][0] for i in self.edgeLabelAttributes])
1273            self.networkCanvas.set_edge_labels(self.lastEdgeLabelAttributes)
1274            self.networkCanvas.replot()
1275
1276        def set_node_colors(self):
1277            if self.graph is None:
1278                return
1279
1280            self.networkCanvas.set_node_colors(self.colorCombo.currentText())
1281            self.lastColorColumn = self.colorCombo.currentText()
1282
1283        def set_edge_colors(self):
1284            if self.graph is None:
1285                return
1286
1287            self.networkCanvas.set_edge_colors(self.edgeColorCombo.currentText())
1288            self.lastEdgeColorColumn = self.edgeColorCombo.currentText()
1289
1290        def set_edge_sizes(self):
1291            if self.graph is None:
1292                return
1293
1294            self.networkCanvas.networkCurve.set_edge_sizes(self.maxLinkSize)
1295            self.networkCanvas.replot()
1296
1297        def set_node_sizes(self):
1298            if self.graph is None or self.networkCanvas is None:
1299                return
1300
1301            if self.minVertexSize > self.maxVertexSize:
1302                self.maxVertexSize = self.minVertexSize
1303
1304            items = self.graph_base.items()
1305
1306            if items is None:
1307                self.networkCanvas.networkCurve.set_node_sizes({}, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1308                return
1309
1310            self.lastVertexSizeColumn = self.vertexSizeCombo.currentText()
1311            column = str(self.vertexSizeCombo.currentText())
1312
1313            values = {}
1314            if column in items.domain or (column.startswith("num of ") and column.replace("num of ", "") in items.domain):
1315                if column in items.domain:
1316                    values = dict((x, items[x][column].value) for x in self.graph if not items[x][column].isSpecial())
1317                else:
1318                    values = dict((x, len(items[x][column.replace("num of ", "")].value.split(','))) for x in self.graph)
1319
1320            if len(values) == 0:
1321                values = dict((node, 1.) for node in self.graph)
1322
1323            if self.invertSize:
1324                maxval = max(values.itervalues())
1325                values.update((key, maxval - val) for key, val in values.iteritems())
1326                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1327            else:
1328                self.networkCanvas.networkCurve.set_node_sizes(values, min_size=self.minVertexSize, max_size=self.maxVertexSize)
1329
1330            self.networkCanvas.replot()
1331
1332        def set_font(self):
1333            if self.networkCanvas is None:
1334                return
1335
1336            weights = {0: 50, 1: 80}
1337
1338            font = self.networkCanvas.font()
1339            font.setPointSize(self.fontSize)
1340            font.setWeight(weights[self.fontWeight])
1341            self.networkCanvas.setFont(font)
1342            self.networkCanvas.fontSize = font
1343            self.networkCanvas.set_node_labels()
1344
1345        def sendReport(self):
1346            self.reportSettings("Graph data",
1347                                [("Number of vertices", self.graph.number_of_nodes()),
1348                                 ("Number of edges", self.graph.number_of_edges()),
1349                                 ("Vertices per edge", "%.3f" % self.verticesPerEdge),
1350                                 ("Edges per vertex", "%.3f" % self.edgesPerVertex),
1351                                 ])
1352            if self.color or self.vertexSize or self.markerAttributes or self.edgeColor:
1353                self.reportSettings("Visual settings",
1354                                    [self.color and ("Vertex color", self.colorCombo.currentText()),
1355                                     self.vertexSize and ("Vertex size", str(self.vertexSizeCombo.currentText()) + " (inverted)" if self.invertSize else ""),
1356                                     self.markerAttributes and ("Labels", ", ".join(self.attributes[i][0] for i in self.markerAttributes)),
1357                                     self.edgeColor and ("Edge colors", self.edgeColorCombo.currentText()),
1358                                    ])
1359            self.reportSettings("Optimization",
1360                                [("Method", self.optCombo.currentText()),
1361                                 ("Iterations", self.frSteps)])
1362            self.reportSection("Graph")
1363            self.reportImage(self.networkCanvas.saveToFileDirect)
1364
1365        #######################################################################
1366        ### PROTOTYPE                                                       ###
1367        #######################################################################
1368
1369        def set_component_edge_width(self, changedMin=True):
1370            if self.networkCanvas is None:
1371                return
1372
1373            canvas = self.networkCanvas
1374            if changedMin:
1375                if self.maxComponentEdgeWidth < self.minComponentEdgeWidth:
1376                    self.maxComponentEdgeWidth = self.minComponentEdgeWidth
1377            else:
1378                if self.minComponentEdgeWidth > self.maxComponentEdgeWidth:
1379                    self.minComponentEdgeWidth = self.maxComponentEdgeWidth
1380
1381            canvas.minComponentEdgeWidth = self.minComponentEdgeWidth
1382            canvas.maxComponentEdgeWidth = self.maxComponentEdgeWidth
1383            self.networkCanvas.updateCanvas()
1384
1385        def showComponents(self):
1386            if self.graph is None or self.graph_base.items() is None:
1387                return
1388
1389            vars = [x.name for x in self.graph_base.items_vars()]
1390
1391            if not self.showComponentCombo.currentText() in vars:
1392                self.networkCanvas.showComponentAttribute = None
1393                self.lastNameComponentAttribute = ''
1394            else:
1395                self.networkCanvas.showComponentAttribute = self.showComponentCombo.currentText()
1396
1397            self.networkCanvas.drawComponentKeywords()
1398
1399        def nameComponents(self):
1400            """Names connected components of genes according to GO terms."""
1401            self.progressBarFinished()
1402            self.lastNameComponentAttribute = None
1403
1404            if self.graph is None or self.graph_base.items() is None:
1405                return
1406
1407            vars = [x.name for x in self.graph_base.items_vars()]
1408            if not self.nameComponentCombo.currentText() in vars:
1409                return
1410
1411            self.progressBarInit()
1412            components = [c for c in Orange.network.nx.algorithms.components.connected_components(self.graph) if len(c) > 1]
1413            if 'component name' in self.graph_base.items().domain:
1414                keyword_table = self.graph_base.items()
1415            else:
1416                keyword_table = Orange.data.Table(Orange.data.Domain(Orange.feature.String('component name')), [[''] for i in range(len(self.graph_base.items()))])
1417
1418            import obiGO
1419            ontology = obiGO.Ontology.Load(progressCallback=self.progressBarSet)
1420            annotations = obiGO.Annotations.Load(self.organism, ontology=ontology, progressCallback=self.progressBarSet)
1421
1422            allGenes = set([e[str(self.nameComponentCombo.currentText())].value for e in self.graph_base.items()])
1423            foundGenesets = False
1424            if len(annotations.geneNames & allGenes) < 1:
1425                allGenes = set(reduce(operator.add, [e[str(self.nameComponentCombo.currentText())].value.split(', ') for e in self.graph_base.items()]))
1426                if len(annotations.geneNames & allGenes) < 1:
1427                    self.warning('no genes found')
1428                    return
1429                else:
1430                    foundGenesets = True
1431
1432            def rank(a, j, reverse=False):
1433                if len(a) <= 0: return
1434
1435                if reverse:
1436                    a.sort(lambda x, y: 1 if x[j] > y[j] else -1 if x[j] < y[j] else 0)
1437                    top_value = a[0][j]
1438                    top_rank = len(a)
1439                    max_rank = float(len(a))
1440                    int_ndx = 0
1441                    for k in range(len(a)):
1442                        if top_value < a[k][j]:
1443                            top_value = a[k][j]
1444                            if k - int_ndx > 1:
1445                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1446                                for l in range(int_ndx, k):
1447                                    a[l][j] = avg_rank
1448
1449                            int_ndx = k
1450
1451                        a[k][j] = top_rank / max_rank
1452                        top_rank -= 1
1453
1454                    k += 1
1455                    if k - int_ndx > 1:
1456                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1457                        for l in range(int_ndx, k):
1458                            a[l][j] = avg_rank
1459
1460                else:
1461                    a.sort(lambda x, y: 1 if x[j] < y[j] else -1 if x[j] > y[j] else 0)
1462                    top_value = a[0][j]
1463                    top_rank = len(a)
1464                    max_rank = float(len(a))
1465                    int_ndx = 0
1466                    for k in range(len(a)):
1467                        if top_value > a[k][j]:
1468                            top_value = a[k][j]
1469                            if k - int_ndx > 1:
1470                                avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1471                                for l in range(int_ndx, k):
1472                                    a[l][j] = avg_rank
1473
1474                            int_ndx = k
1475
1476                        a[k][j] = top_rank / max_rank
1477                        top_rank -= 1
1478
1479                    k += 1
1480                    if k - int_ndx > 1:
1481                        avg_rank = (a[int_ndx][j] + a[k - 1][j]) / 2
1482                        for l in range(int_ndx, k):
1483                            a[l][j] = avg_rank
1484
1485            for i in range(len(components)):
1486                component = components[i]
1487                if len(component) <= 1:
1488                    continue
1489
1490                if foundGenesets:
1491                    genes = reduce(operator.add, [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value.split(', ') for v in component])
1492                else:
1493                    genes = [self.graph_base.items()[v][str(self.nameComponentCombo.currentText())].value for v in component]
1494
1495                res1 = annotations.GetEnrichedTerms(genes, aspect="P")
1496                res2 = annotations.GetEnrichedTerms(genes, aspect="F")
1497                res = res1.items() + res2.items()
1498                #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]
1499                #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]
1500
1501                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]
1502                if len(namingScore) == 0:
1503                    continue
1504
1505                annotated_genes = max([a[0] for a in namingScore])
1506
1507                rank(namingScore, 1, reverse=True)
1508                rank(namingScore, 2, reverse=True)
1509                rank(namingScore, 0)
1510
1511                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]
1512                namingScore.sort(reverse=True)
1513
1514                if len(namingScore) < 1:
1515                    print "warning. no annotations found for group of genes: " + ", ".join(genes)
1516                    continue
1517                elif len(namingScore[0]) < 2:
1518                    print "warning. error computing score for group of genes: " + ", ".join(genes)
1519                    continue
1520
1521                for v in component:
1522                    name = str(namingScore[0][1])
1523                    attrs = "%d/%d, %d, %lf" % (namingScore[0][2], annotated_genes, namingScore[0][3], namingScore[0][4])
1524                    info = ''
1525                    if self.showTextMiningInfo:
1526                        info = "\n" + attrs + "\n" + str(namingScore[0][0])
1527                    keyword_table[v]['component name'] = name + info
1528
1529                self.progressBarSet(i * 100.0 / len(components))
1530
1531            self.lastNameComponentAttribute = self.nameComponentCombo.currentText()
1532            self.set_items(Orange.data.Table([self.graph_base.items(), keyword_table]))
1533            self.progressBarFinished()
1534
1535
1536        def setAutoSendAttributes(self):
1537            print 'TODO setAutoSendAttributes'
1538            #if self.autoSendAttributes:
1539            #    self.networkCanvas.callbackSelectVertex = self.sendAttSelectionList
1540            #else:
1541            #    self.networkCanvas.callbackSelectVertex = None
1542
1543        def sendAttSelectionList(self):
1544            if not self.graph is None:
1545                vars = [x.name for x in self.graph_base.links_vars()]
1546                if not self.comboAttSelection.currentText() in vars:
1547                    return
1548                att = str(self.comboAttSelection.currentText())
1549                vertices = self.networkCanvas.selected_nodes()
1550
1551                if len(vertices) != 1:
1552                    return
1553
1554                attributes = str(self.graph_base.items()[vertices[0]][att]).split(', ')
1555            else:
1556                attributes = None
1557            self.send("Features", attributes)
1558
1559
1560except ImportError as err:
1561    try:
1562        from OWNxCanvas import *
1563    except:
1564        # if Qwt is also not installed throw could not import orangeqt error
1565        raise err
1566
1567    from OWNxExplorerQwt import OWNxExplorerQwt as OWNxExplorer
1568
1569if __name__ == "__main__":
1570    a = QApplication(sys.argv)
1571    ow = OWNxExplorer()
1572    ow.show()
1573
1574    def setNetwork(signal, data, id=None):
1575        if signal == 'Network':
1576            ow.set_graph(data)
1577        #if signal == 'Items':
1578        #    ow.set_items(data)
1579
1580    import OWNxFile
1581    owFile = OWNxFile.OWNxFile()
1582    owFile.send = setNetwork
1583    owFile.show()
1584    owFile.selectNetFile(0)
1585
1586    a.exec_()
1587    ow.saveSettings()
1588    owFile.saveSettings()
Note: See TracBrowser for help on using the repository browser.