source: orange/Orange/OrangeWidgets/Unsupervised/OWNxExplorer.py @ 10496:e4a59430af42

Revision 10496:e4a59430af42, 73.6 KB checked in by Lan Zagar <lan.zagar@…>, 2 years ago (diff)

Added some options to settingsList and forced their application after graph change (this part has to be checked), see #1136.

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