source: orange/orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 9627:2c837d8030f4

Revision 9627:2c837d8030f4, 73.1 KB checked in by Miha Stajdohar <miha.stajdohar@…>, 2 years ago (diff)

Added save network feature.

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